本文主要是介绍PHP7扩展开发之数组处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
这次,我们将演示如何在PHP扩展中如何对数组进行处理。要实现的PHP代码如下:
<?php
function array_concat ($arr, $prefix) {foreach($arr as $key => $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扩展相关代码大家请看这篇博文。PHP7扩展开发之hello word 文中已经详细介绍了如何创建一个扩展和提供了源码下载。
实现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://jpauli.github.io/2016/04/08/hashtables.html
源码下载
tar.gz格式下载
zip格式下载
原文链接:PHP7扩展开发之数组处理
这篇关于PHP7扩展开发之数组处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!