PHP7扩展开发之数组处理

简介: # 前言 这次,我们将演示如何在PHP扩展中如何对数组进行处理。要实现的PHP代码如下: ```php ``` 把两个数组,相同key的字符串值拼接。 # 代码 ## 基础代码 这个扩展,我们将在say扩展上增加 ``array_concat`` 方法。say扩展相关代码大家请看这篇博文。[PHP7扩展开发之hello word](http://www.bo56.com

前言

这次,我们将演示如何在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

更多函数说明请查看

目录
相关文章
|
13天前
|
设计模式 安全 关系型数据库
PHP开发涉及一系列步骤和技术
【7月更文挑战第2天】PHP开发涉及一系列步骤和技术
114 57
|
3天前
|
安全 大数据 编译器
PHP 8: 探索新特性及其对现代Web开发的影响
在这篇文章中,我们将深入探讨PHP 8的最新特性,包括JIT编译器、联合类型、匹配表达式等,并分析这些更新如何影响现代Web开发。通过具体示例和代码片段,本文旨在为开发者提供一个清晰的指南,以便更好地利用PHP 8的新功能优化和加速他们的应用程序。
10 2
|
3天前
|
编译器 测试技术 PHP
深入理解PHP 7的新特性及其对现代Web开发的影响
【7月更文挑战第12天】本文将探讨PHP 7版本中引入的关键改进和新增功能,以及这些变化如何优化了性能、提升了代码的可维护性,并促进了现代Web开发的最佳实践。通过具体示例,我们将深入了解这些新特性在日常开发中的应用,以及它们为开发者带来的实际益处。
10 2
|
3天前
|
PHP 开发者
PHP 8 新特性及其对现代Web开发的影响
PHP 8作为最新版本,引入了一系列强大的新特性和改进,这些变化不仅仅是语言本身的提升,更深刻地影响了现代Web开发的方式和效率。本文将深入探讨PHP 8的关键特性,分析其在开发实践中的应用和优势,帮助开发者更好地理解和利用这些新特性。 【7月更文挑战第12天】
9 1
|
7天前
|
安全 编译器 PHP
深入理解PHP 8的新特性及其对现代Web开发的影响
【7月更文挑战第8天】随着PHP 8的发布,这个广受欢迎的服务器端脚本语言迎来了重大更新,带来了性能提升和更现代化的编程特性。本文将探索PHP 8中的新特性,并分析它们如何改变开发者构建和维护Web应用的方式,同时指出这些变化对现有项目升级可能带来的挑战与机遇。
|
10天前
|
设计模式 Rust 安全
深入理解PHP 7的新特性及其对现代Web开发的影响
本文通过数据驱动的分析,探讨了PHP 7的发布如何革新了Web开发的面貌。文章首先概述了PHP 7带来的性能提升与新特性,然后通过实际案例和性能测试数据,详细讨论了这些新特性对提高代码效率、增强安全性和支持现代编程范式的具体影响。最后,文章将评估PHP 7在当前Web开发环境中的地位,并对其未来的发展做出展望。
|
13天前
|
Serverless PHP
【PHP常用函数封装】 php 判断两个数组所有的值是否是完全相等
【PHP常用函数封装】 php 判断两个数组所有的值是否是完全相等
19 3
|
13天前
|
Serverless PHP
【PHP常用函数封装】 php 判断a数组里是否完全包含b数组
【PHP常用函数封装】 php 判断a数组里是否完全包含b数组
15 1
|
14天前
|
算法 测试技术 PHP
通过阶乘获取一个一维PHP数组中全部的组合情况
在PHP中,`FactorialHandler`类通过递归实现了数组的全组合,`getArrAllCombineByFactor`方法逐个添加元素至所有子组合中。示例代码展示了一个包含组合生成的过程,输出了所有可能的排列。此外,还提供了一个深度优先搜索的递归函数`depth_picker`,用于生成数组的所有组合,从选择单个元素到选择所有元素。这两个示例揭示了递归在处理数组组合问题中的应用,常见于算法设计和测试用例生成。
9 0
通过阶乘获取一个一维PHP数组中全部的组合情况
|
16天前
|
安全 编译器 API
探索PHP 8的新特性及其对现代Web开发的影响
随着PHP 8的正式发布,这一版本带来了多项重大改进和新特性,旨在提升性能、增加语言的灵活性并简化开发流程。本文将详细探讨PHP 8中的关键更新,包括JIT编译器、联合类型、命名参数、匹配表达式等,并分析这些新特性如何影响现代Web开发的实践。通过引用最新的性能数据和开发者反馈,我们将深入理解PHP 8带来的变革,以及它对现有项目和未来趋势的潜在影响。