php内置函数分析array_diff()
PHP_FUNCTION(array_diff)
{
zval *args;
int argc, i;
uint32_t num;
HashTable exclude;
zval *value;
zend_string *str, *key;
zend_long idx;
zval dummy; // 至少两个参数
if (ZEND_NUM_ARGS() < ) {
php_error_docref(NULL, E_WARNING, "at least 2 parameters are required, %d given", ZEND_NUM_ARGS());
return;
}
// 类型描述符:* variable arguments list (0 or more)
// 类型描述符:+ variable arguments list (1 or more)
// 参数存放在数组args中,argc保存参数个数
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
return;
} // 第一个参数不是数组,则报错
if (Z_TYPE(args[]) != IS_ARRAY) {
php_error_docref(NULL, E_WARNING, "Argument #1 is not an array");
RETURN_NULL(); // 返回NULL
} /* count number of elements */
// 检查所有参数是否是数组
num = ;
for (i = ; i < argc; i++) {
if (Z_TYPE(args[i]) != IS_ARRAY) {
php_error_docref(NULL, E_WARNING, "Argument #%d is not an array", i + );
RETURN_NULL(); // 返回NULL
}
num += zend_hash_num_elements(Z_ARRVAL(args[i])); // 所有参数数组的元素个数累加
} // 元素个数num为0,返回第一个参数数组(空数组)
if (num == ) {
ZVAL_COPY(return_value, &args[]);
return;
} ZVAL_NULL(&dummy);
/* create exclude map */
zend_hash_init(&exclude, num, NULL, NULL, );
// 从第二个数组开始,所以数组元素保存到exclude
for (i = ; i < argc; i++) {
// 遍历数组
ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL(args[i]), value) {
str = zval_get_string(value); // 数组元素值转为字符串
zend_hash_add(&exclude, str, &dummy); //
zend_string_release(str);
} ZEND_HASH_FOREACH_END();
} /* copy all elements of first array that are not in exclude set */
// 初始化返回值数组,大小和第一个数组一致。
array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL(args[])));
// 循环遍历第一个数组
ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL(args[]), idx, key, value) {
str = zval_get_string(value); // 元素值转为字符串
if (!zend_hash_exists(&exclude, str)) { // exclude中找不到该值
// 插入到返回值数组中(差集),键名保留不变。
if (key) {
value = zend_hash_add_new(Z_ARRVAL_P(return_value), key, value);
} else {
value = zend_hash_index_add_new(Z_ARRVAL_P(return_value), idx, value);
}
zval_add_ref(value);
}
zend_string_release(str);
} ZEND_HASH_FOREACH_END(); zend_hash_destroy(&exclude);
}
php内置函数分析array_diff()的更多相关文章
- map内置函数分析所得到的思路
map:会根据提供的函数对指定序列做映射. map(func, *iterables) --> map object Make an iterator that computes the fun ...
- php内置函数分析之array_diff_assoc()
static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_type) /* {{{ */ { uint ...
- php内置函数分析之array_combine()
PHP_FUNCTION(array_combine) { HashTable *values, *keys; uint32_t pos_values = ; zval *entry_keys, *e ...
- php内置函数分析之ucwords()
PHP_FUNCTION(ucwords) { zend_string *str; char *delims = " \t\r\n\f\v"; register char *r, ...
- php内置函数分析之strtoupper()、strtolower()
strtoupper(): PHP_FUNCTION(strtoupper) { zend_string *str; ZEND_PARSE_PARAMETERS_START(, ) Z_PARAM_S ...
- php内置函数分析之ucfirst()、lcfirst()
ucfirst($str) 将 str 的首字符(如果首字符是字母)转换为大写字母,并返回这个字符串. 源码位于 ext/standard/string.c /* {{{ php_ucfirst Up ...
- php内置函数分析之trim()
官方手册中: 类似函数还有两个:ltrim() 和 rtrim().分别处理字符串的左侧.右侧. trim()的具体实现位于:ext/standard/string.c /* {{{ proto st ...
- php内置函数分析之str_pad()
PHP_FUNCTION(str_pad) { /* Input arguments */ zend_string *input; /* Input string 输入字符串*/ zend_long ...
- php内置函数分析之array_fill_keys()
PHP_FUNCTION(array_fill_keys) { zval *keys, *val, *entry; if (zend_parse_parameters(ZEND_NUM_ARGS(), ...
随机推荐
- laravel中model类中好用的方法
public function field() { return $this->belongsTo(HrmAuthFieldsModel::class, 'filed_id', 'id'); } ...
- WAMP搭建与配置
使用WampServer整合软件包进行WAMP环境搭建 WampServer是一款由法国人开发的Apache Web服务器.PHP解释器以及MySQL数据库的整合软件包.免去了开发人员将时间花费在繁琐 ...
- idea中@data不生效
idea中@data不生效,原因是idea中没有安装插件,记得重启
- RabbitMQ安装及其中遇到的问题解决方案
参考官方文档:https://www.rabbitmq.com/install-debian.html#apt 第一步: # import PackageCloud signing key wget ...
- 【漏洞学习】HOST 头攻击漏洞
日期:2018-03-06 14:32:51 作者:Bay0net 0x01. 前言 在一般情况下,几个网站可能会放在同一个服务器上,或者几个 web 系统共享一个服务器,host 头来指定应该由哪个 ...
- 自动爬取代理IP例子
import time import json import datetime import threading import requests from lxml import etree from ...
- 系统分析与设计HW7
XX 建模练习 要求: 练习文档编写 选择一个你喜欢的 移动App 或 其中某业务 参考 Asg_RH 文档格式 编写软件描述 文档要包含一个业务的完整过程 建模要求包括(用例图.XX业务或用例的活动 ...
- Apache hadoop namenode ha和yarn ha ---HDFS高可用性
HDFS高可用性Hadoop HDFS 的两大问题:NameNode单点:虽然有StandbyNameNode,但是冷备方案,达不到高可用--阶段性的合并edits和fsimage,以缩短集群启动的时 ...
- jmeter常用性能监听器分析
jmeter中提供了很多性能数据的监听器,我们通过监听器可以来分析性能瓶颈 本文以500线程的阶梯加压测试结果来描述图表. 常用监听器 1:Transactions per Second 监听动态TP ...
- LeetCode算法题-Flipping an Image(Java实现)
这是悦乐书的第324次更新,第347篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第194题(顺位题号是832).给定二进制矩阵A,我们想要水平翻转图像,然后反转它,并返 ...