博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP7扩展开发之数组处理
阅读量:6161 次
发布时间:2019-06-21

本文共 3359 字,大约阅读时间需要 11 分钟。

前言

这次,我们将演示如何在PHP扩展中如何对数组进行处理。要实现的PHP代码如下:

$val) { if (isset($prefix[$key]) && is_string($val) && is_string($prefix[$key])) { $arr[$key] = $prefix[$key].$val; } } return $arr; } $arr = array( 0 => '0', 1 => '123', 'a' => 'abc', ); $prefix = array( 1 => '456', 'a' => 'def', ); var_dump(array_concat($arr, $prefix)); ?>
把两个数组,相同key的字符串值拼接。

代码

基础代码

这个扩展,我们将在say扩展上增加 array_concat 方法。say扩展相关代码大家请看这篇博文。 文中已经详细介绍了如何创建一个扩展和提供了源码下载。

实现array_concat方法

array_concat方法的PHP扩展源码:

PHP_FUNCTION(array_concat){    zval *arr, *prefix, *entry, *prefix_entry, value;    zend_string *string_key, *result;    zend_ulong num_key;    if (zend_parse_parameters(ZEND_NUM_ARGS(), "aa", &arr, &prefix) == FAILURE) {        return;    }    array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(arr)));        ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(arr), num_key, string_key, entry) {        if (string_key && zend_hash_exists(Z_ARRVAL_P(prefix), string_key)) {            prefix_entry = zend_hash_find(Z_ARRVAL_P(prefix), string_key);            if (Z_TYPE_P(entry) == IS_STRING && prefix_entry != NULL && Z_TYPE_P(prefix_entry) == IS_STRING) {                result = strpprintf(0, "%s%s", Z_STRVAL_P(prefix_entry), Z_STRVAL_P(entry));                ZVAL_STR(&value, result);                zend_hash_update(Z_ARRVAL_P(return_value), string_key, &value);            }           } else if (string_key == NULL && zend_hash_index_exists(Z_ARRVAL_P(prefix), num_key)){            prefix_entry = zend_hash_index_find(Z_ARRVAL_P(prefix), num_key);            if (Z_TYPE_P(entry) == IS_STRING && prefix_entry != NULL && Z_TYPE_P(prefix_entry) == IS_STRING) {                result = strpprintf(0, "%s%s", Z_STRVAL_P(prefix_entry), Z_STRVAL_P(entry));                ZVAL_STR(&value, result);                zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, &value);            }        } else if (string_key) {            zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry);            zval_add_ref(entry);        } else  {            zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry);            zval_add_ref(entry);        }    }ZEND_HASH_FOREACH_END();}

代码说明

PHP中的数组本质上就是一个哈希。

对于哈希处理的方法主要集中在Zend/zend_hash.h中。
对于数组的操作方法主要集中在Zend/API.h。数组的方法其实就是对哈希处理方法的一层包装。
数组操作的方法主要是以add_assoc_add_index_开头的一些列方法。

下面是代码中涉及的一些方法。

zend_hash_num_elements获取数组的元素个数。

array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(arr))); 初始化一个数组。在PHP扩展中,我们是通过return_value这个变量设置方法的返回值。因此,我们直接修改这个return_value变量即可。感兴趣的话,可以把宏方法PHP_FUNCTION展开看下。

PHP7提供了一套宏方法用于遍历哈希和对哈希进行操作。这些宏方法主要放在Zend/zend_hash.h文件中。如,代码中的ZEND_HASH_FOREACH_KEY_VAL就是一个变量哈希的宏。是不是和PHP代码中的foreach有点像?

在这里我们把代码中用到的哈希相关的方法做下整理说明:

ZEND_HASH_FOREACH_KEY_VAL 和 ZEND_HASH_FOREACH_END 配合使用,实现foreach的效果。
zend_hash_exists 检测指定的key在哈希中是否存在。key为字符串。
zend_hash_index_exists 检测指定的key在哈希中是否存在。key为数字。
zend_hash_find 根据key查找指定的值。key为字符串。
zend_hash_index_find 根据key查找指定的值。key为数字。
zend_hash_update 更新指定key的值。key为字符串。
zend_hash_index_update 更新指定key的值。key为数字。
基本上有这些方法,你就可以对数组进行一些基本操作了。方法命名也很有规律,key为字符串和数字提供了两套。

zval_add_ref(entry); 给数组的值,增加一次引用计数。zend_hash_update方法只自动给string_key自动增加了一次引用计数。数组return_value共用数组arr的值。因此,我们需要手动增加一次引用计数。

PHP7哈希相关的文章大家可以看看

转载地址:http://hklfa.baihongyu.com/

你可能感兴趣的文章
一个屌丝程序猿的人生(六十六)
查看>>
Java 编码 UTF-8
查看>>
SpringMVC实战(注解)
查看>>
关于静态属性和静态函数
查看>>
进程的基本属性:进程ID、父进程ID、进程组ID、会话和控制终端
查看>>
spring+jotm+ibatis+mysql实现JTA分布式事务
查看>>
MyBatis启动:MapperStatement创建
查看>>
调查问卷相关
查看>>
eclipse启动无响应,老是加载不了revert resources,或停留在Loading workbench状态
查看>>
1. Git-2.12.0-64-bit .exe下载
查看>>
怎样关闭“粘滞键”?
查看>>
[转]React 教程
查看>>
拓扑排序介绍
查看>>
eclipse打开工作空间(workspace)没有任务反应
查看>>
使用Sybmol模块来构建神经网络
查看>>
字符串去分割符号
查看>>
WPF中,多key值绑定问题,一个key绑定一个界面上的对象
查看>>
UML类图简明教程
查看>>
java反编译工具(Java Decompiler)
查看>>
Android开发之自定义对话框
查看>>