PHP7扩展开发之数组处理

2024-09-08 14:18
文章标签 数组 开发 处理 扩展 php7

本文主要是介绍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_VALZEND_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扩展开发之数组处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1148343

相关文章

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

Python视频处理库VidGear使用小结

《Python视频处理库VidGear使用小结》VidGear是一个高性能的Python视频处理库,本文主要介绍了Python视频处理库VidGear使用小结,文中通过示例代码介绍的非常详细,对大家的... 目录一、VidGear的安装二、VidGear的主要功能三、VidGear的使用示例四、VidGea

Python结合requests和Cheerio处理网页内容的操作步骤

《Python结合requests和Cheerio处理网页内容的操作步骤》Python因其简洁明了的语法和强大的库支持,成为了编写爬虫程序的首选语言之一,requests库是Python中用于发送HT... 目录一、前言二、环境搭建三、requests库的基本使用四、Cheerio库的基本使用五、结合req

使用Python处理CSV和Excel文件的操作方法

《使用Python处理CSV和Excel文件的操作方法》在数据分析、自动化和日常开发中,CSV和Excel文件是非常常见的数据存储格式,ython提供了强大的工具来读取、编辑和保存这两种文件,满足从基... 目录1. CSV 文件概述和处理方法1.1 CSV 文件格式的基本介绍1.2 使用 python 内

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

SpringBoot操作spark处理hdfs文件的操作方法

《SpringBoot操作spark处理hdfs文件的操作方法》本文介绍了如何使用SpringBoot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Ser... 目录SpringBoot操作spark处理hdfs文件1、导入依赖2、配置spark信息3、cont

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo