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(), ...
随机推荐
- 1. JDK 、 JRE 、JVM有什么区别和联系?
首先,我们分别对这三者进行阐述. JVM :英文名称(Java Virtual Machine),就是我们耳熟能详的 Java 虚拟机.它只认识 xxx.class 这种类型的文件,它能够将 clas ...
- DeepFaceLab报错,integer division or modulo by zero
DeepFaceLab的集成环境在众多换脸软件中是做的最好的.但是使用过程也会出现一些错误,主要的错误有两个,一个是你配置太低OOM了,主要体现显存太低.第二个是版本不对应.比如你原先用的cuda9. ...
- 四十三、jenkins启动时报错:consider increasing the maximum size of the cache. After eviction approximately [10,239] KB of data
jenkins启动时报错: consider increasing the maximum size of the cache. After eviction approximately [10,23 ...
- RotateZoom.cpp 20180622
20180622代码加入随意变换图像大小 批处理框架先不看:-B src3.bmp 10 1 30 2 0.1 3 tar.bmp src2.bmp 37.5 2.1 tar // RotateZo ...
- C# App.config全攻略
读语句: String str = ConfigurationManager.AppSettings["DemoKey"]; 写语句: Configuration ...
- zabbix添加主机后无法显示解决
第一次添加主机后显示正常,后来删除了主机,重新添加了一下主机再也无法显示主机,很苦恼,原来需要点击重设,
- 【ABAP系列】SAP ABAP 刷新SCREEN的方法
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 刷新SCREE ...
- Go语言入门篇-项目常见用法&语法
一.导入包用法: //_表示仅执行该包下的init函数(不需要整个包导入) import _ "git.xx.xx/baases/identity/cachain/version" ...
- docker之配置TensorFlow的运行环境
Docker是一种 操作系统层面的虚拟化技术,类似于传统的虚拟机.传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程:而容器内的应用进程直接运行于宿主的内核,容 ...
- 发布项目到github上web服务器来运行
$ git add dist Administrator@LuoTong- MINGW32 /D/react_workspace (master) $ git commit -m "git ...