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()的更多相关文章

  1. map内置函数分析所得到的思路

    map:会根据提供的函数对指定序列做映射. map(func, *iterables) --> map object Make an iterator that computes the fun ...

  2. php内置函数分析之array_diff_assoc()

    static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_type) /* {{{ */ { uint ...

  3. php内置函数分析之array_combine()

    PHP_FUNCTION(array_combine) { HashTable *values, *keys; uint32_t pos_values = ; zval *entry_keys, *e ...

  4. php内置函数分析之ucwords()

    PHP_FUNCTION(ucwords) { zend_string *str; char *delims = " \t\r\n\f\v"; register char *r, ...

  5. php内置函数分析之strtoupper()、strtolower()

    strtoupper(): PHP_FUNCTION(strtoupper) { zend_string *str; ZEND_PARSE_PARAMETERS_START(, ) Z_PARAM_S ...

  6. php内置函数分析之ucfirst()、lcfirst()

    ucfirst($str) 将 str 的首字符(如果首字符是字母)转换为大写字母,并返回这个字符串. 源码位于 ext/standard/string.c /* {{{ php_ucfirst Up ...

  7. php内置函数分析之trim()

    官方手册中: 类似函数还有两个:ltrim() 和 rtrim().分别处理字符串的左侧.右侧. trim()的具体实现位于:ext/standard/string.c /* {{{ proto st ...

  8. php内置函数分析之str_pad()

    PHP_FUNCTION(str_pad) { /* Input arguments */ zend_string *input; /* Input string 输入字符串*/ zend_long ...

  9. php内置函数分析之array_fill_keys()

    PHP_FUNCTION(array_fill_keys) { zval *keys, *val, *entry; if (zend_parse_parameters(ZEND_NUM_ARGS(), ...

随机推荐

  1. laravel中model类中好用的方法

    public function field() { return $this->belongsTo(HrmAuthFieldsModel::class, 'filed_id', 'id'); } ...

  2. WAMP搭建与配置

    使用WampServer整合软件包进行WAMP环境搭建 WampServer是一款由法国人开发的Apache Web服务器.PHP解释器以及MySQL数据库的整合软件包.免去了开发人员将时间花费在繁琐 ...

  3. idea中@data不生效

    idea中@data不生效,原因是idea中没有安装插件,记得重启

  4. RabbitMQ安装及其中遇到的问题解决方案

    参考官方文档:https://www.rabbitmq.com/install-debian.html#apt 第一步: # import PackageCloud signing key wget ...

  5. 【漏洞学习】HOST 头攻击漏洞

    日期:2018-03-06 14:32:51 作者:Bay0net 0x01. 前言 在一般情况下,几个网站可能会放在同一个服务器上,或者几个 web 系统共享一个服务器,host 头来指定应该由哪个 ...

  6. 自动爬取代理IP例子

    import time import json import datetime import threading import requests from lxml import etree from ...

  7. 系统分析与设计HW7

    XX 建模练习 要求: 练习文档编写 选择一个你喜欢的 移动App 或 其中某业务 参考 Asg_RH 文档格式 编写软件描述 文档要包含一个业务的完整过程 建模要求包括(用例图.XX业务或用例的活动 ...

  8. Apache hadoop namenode ha和yarn ha ---HDFS高可用性

    HDFS高可用性Hadoop HDFS 的两大问题:NameNode单点:虽然有StandbyNameNode,但是冷备方案,达不到高可用--阶段性的合并edits和fsimage,以缩短集群启动的时 ...

  9. jmeter常用性能监听器分析

    jmeter中提供了很多性能数据的监听器,我们通过监听器可以来分析性能瓶颈 本文以500线程的阶梯加压测试结果来描述图表. 常用监听器 1:Transactions per Second 监听动态TP ...

  10. LeetCode算法题-Flipping an Image(Java实现)

    这是悦乐书的第324次更新,第347篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第194题(顺位题号是832).给定二进制矩阵A,我们想要水平翻转图像,然后反转它,并返 ...