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

相关文章

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

基于Python开发PPTX压缩工具

《基于Python开发PPTX压缩工具》在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,不便于传输和存储,所以本文将使用Python开发一个PPTX压缩工具,需要的可以了解下... 目录引言全部代码环境准备代码结构代码实现运行结果引言在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

Spring Boot 整合 ShedLock 处理定时任务重复执行的问题小结

《SpringBoot整合ShedLock处理定时任务重复执行的问题小结》ShedLock是解决分布式系统中定时任务重复执行问题的Java库,通过在数据库中加锁,确保只有一个节点在指定时间执行... 目录前言什么是 ShedLock?ShedLock 的工作原理:定时任务重复执行China编程的问题使用 Shed

Redis如何使用zset处理排行榜和计数问题

《Redis如何使用zset处理排行榜和计数问题》Redis的ZSET数据结构非常适合处理排行榜和计数问题,它可以在高并发的点赞业务中高效地管理点赞的排名,并且由于ZSET的排序特性,可以轻松实现根据... 目录Redis使用zset处理排行榜和计数业务逻辑ZSET 数据结构优化高并发的点赞操作ZSET 结

微服务架构之使用RabbitMQ进行异步处理方式

《微服务架构之使用RabbitMQ进行异步处理方式》本文介绍了RabbitMQ的基本概念、异步调用处理逻辑、RabbitMQ的基本使用方法以及在SpringBoot项目中使用RabbitMQ解决高并发... 目录一.什么是RabbitMQ?二.异步调用处理逻辑:三.RabbitMQ的基本使用1.安装2.架构

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.