当前位置: 首页 > news >正文

php array_diff 比较两个数组bug避坑 深入了解

今天实用array_diff出现的异常问题,预想的结果应该是返回 "integral_initiate"=>"0",实际没有

先看测试代码:

$a = ["user_name"=>"测","see_num"=>0,"integral_initiate"=>"0"
];
$b = ["user_name"=>"测","see_num"=>0,"integral_initiate"=>10
];
$gf = array_diff($a,$b);
print_r($gf);

没有返回差异,纠结了好一阵子又查阅了文档看到这一句话才醒悟 

我们简化一下数组来看,通过简化数组发现只要两个数组中间都带有0的值就不会正常效验

解决方案就是换成 array_diff_assoc 对比键名与键值

------------序言--------------

虽然上面得到了想要的结果,但是本着刨根问底的思想继续研究了 一番,查了一些资料,也翻了下源码终于找到了一个合理的解释

/* {{{ proto array array_diff(array arr1, array arr2 [, array ...])Returns the entries of arr1 that have values which are not present in any of the others arguments. */
PHP_FUNCTION(array_diff)
{zval *args;int argc, i;uint32_t num;HashTable exclude;zval *value;zend_string *str, *tmp_str, *key;zend_long idx;zval dummy;if (ZEND_NUM_ARGS() < 2) {php_error_docref(NULL, E_WARNING, "at least 2 parameters are required, %d given", ZEND_NUM_ARGS());return;}ZEND_PARSE_PARAMETERS_START(1, -1)Z_PARAM_VARIADIC('+', args, argc)ZEND_PARSE_PARAMETERS_END();if (Z_TYPE(args[0]) != IS_ARRAY) {php_error_docref(NULL, E_WARNING, "Expected parameter 1 to be an array, %s given", zend_zval_type_name(&args[0]));RETURN_NULL();}num = zend_hash_num_elements(Z_ARRVAL(args[0]));if (num == 0) {for (i = 1; i < argc; i++) {if (Z_TYPE(args[i]) != IS_ARRAY) {php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));RETURN_NULL();}}RETURN_EMPTY_ARRAY();} else if (num == 1) {int found = 0;zend_string *search_str, *tmp_search_str;value = NULL;ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL(args[0]), value) {break;} ZEND_HASH_FOREACH_END();if (!value) {for (i = 1; i < argc; i++) {if (Z_TYPE(args[i]) != IS_ARRAY) {php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));RETURN_NULL();}}RETURN_EMPTY_ARRAY();}search_str = zval_get_tmp_string(value, &tmp_search_str);for (i = 1; i < argc; i++) {if (Z_TYPE(args[i]) != IS_ARRAY) {php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));RETURN_NULL();}if (!found) {ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL(args[i]), value) {str = zval_get_tmp_string(value, &tmp_str);if (zend_string_equals(search_str, str)) {zend_tmp_string_release(tmp_str);found = 1;break;}zend_tmp_string_release(tmp_str);} ZEND_HASH_FOREACH_END();}}zend_tmp_string_release(tmp_search_str);if (found) {RETVAL_EMPTY_ARRAY();} else {ZVAL_COPY(return_value, &args[0]);}return;}/* count number of elements */num = 0;for (i = 1; i < argc; i++) {if (Z_TYPE(args[i]) != IS_ARRAY) {php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));RETURN_NULL();}num += zend_hash_num_elements(Z_ARRVAL(args[i]));}if (num == 0) {ZVAL_COPY(return_value, &args[0]);return;}ZVAL_NULL(&dummy);/* create exclude map */zend_hash_init(&exclude, num, NULL, NULL, 0);for (i = 1; i < argc; i++) {ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL(args[i]), value) {str = zval_get_tmp_string(value, &tmp_str);zend_hash_add(&exclude, str, &dummy);zend_tmp_string_release(tmp_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[0])));ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL(args[0]), idx, key, value) {str = zval_get_tmp_string(value, &tmp_str);if (!zend_hash_exists(&exclude, str)) {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_tmp_string_release(tmp_str);} ZEND_HASH_FOREACH_END();zend_hash_destroy(&exclude);
}
/* }}} */

这就可以解释为什么使用array_diff 不能得到想要的结果,因为只要第一个数组中的值在第二个数组中出现过就不算差异,所以并不是bug,反过来再去看一下文档上面英文注释是这样写的

我只能说这个中文版的翻译有待提升,至此问题就到这里了

相关文档:

1、问题解答: https://stackoverflow.com/questions/4742405/array-diff-to-compare-two-associative-arrays/4742438#4742438 2、PHP 如何查看php函数源码-CSDN博客

3、源码地址 :GitCode - 开发者的代码家园 

相关文章:

php array_diff 比较两个数组bug避坑 深入了解

今天实用array_diff出现的异常问题&#xff0c;预想的结果应该是返回 "integral_initiate">"0"&#xff0c;实际没有 先看测试代码&#xff1a; $a ["user_name">"测","see_num">0,"integral_initiate&quo…...

c++中STL的vector简单实现

文章目录 vector构造函数 vector()拷贝构造 vector()析构函数 ~vector()iterator 的定义begin()与const版本end()与const版本增删改查尾插push_back()尾删pop_back()指定位置插入insert()指定位置删除 erase() operator[]与const版本容量增容reserve()设置容量 resize() 成员函…...

C# 更改Bitmap图像色彩模式

方法一&#xff1a;直接修改RGB的值 首先将BitmapData扫描线上的所有像素复制到字节数组中&#xff0c;然后遍历数组并对每个像素的RGB值进行修改&#xff0c;最后将修改后的像素值复制回BitmapData。这个过程不会影响原始的Bitmap对象&#xff0c;但会改变锁定的位图区域的数…...

5.2 基于深度学习和先验状态的实时指纹室内定位

文献来源 Nabati M, Ghorashi S A. A real-time fingerprint-based indoor positioning using deep learning and preceding states[J]. Expert Systems with Applications, 2023, 213: 118889.&#xff08;5.2_基于指纹的实时室内定位&#xff0c;使用深度学习和前一状态&…...

AIGC时代高效阅读论文实操

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…...

对网站进行打点(不要有主动扫描行为)

什么是打点&#xff1f; 简单来说就是获取一个演习方服务器的控制权限。 目的&#xff1a; 1. 上传一个一句话木马 2. 挖到命令执行 3. 挖到反序列化漏洞 4. 钓鱼 假设对“千峰”网站进行打点&#xff1a; 1. 利用平台 1. 利用各类平台&#xff1a; 天眼查-商业查询平…...

502. IPO(贪心算法+优先队列/堆)

整体思想&#xff1a;在满足可用资金的情况下&#xff0c;选择其中利润最大的业务&#xff0c;直到选到k个业务为止&#xff0c;注意k可能比n大。 每次选择完一个业务&#xff0c;可用资金都会变动&#xff0c;这是可选择的业务也会变化&#xff0c;因此每次将可选择的业务放在…...

设计模式篇---中介者模式

文章目录 概念结构实例总结 概念 中介者模式&#xff1a;用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用&#xff0c;从而使其耦合松散&#xff0c;而且可以独立地改变它们之间的交互。 就好比世界各个国家之间可能会产生冲突&#xff0c;但是当产…...

双端Diff算法

双端Diff算法 双端Diff算法指的是&#xff0c;在新旧两组子节点的四个端点之间分别进行比较&#xff0c;并试图找到可复用的节点。相比简单Diff算法&#xff0c;双端Diff算法的优势在于&#xff0c;对于同样的更新场景&#xff0c;执行的DOM移动操作次数更少。 简单 Diff 算法…...

react+antd,Table表头文字颜色设置

1、创建一个自定义的TableHeaderCell组件&#xff0c;并设置其样式为红色 const CustomTableHeaderCell ({ children }) > (<th style{{ color: "red" }}>{children}</th> ); 2、将CustomTableHeaderCell组件传递到Table组件的columns属性中的titl…...

2024年1月18日Arxiv最热NLP大模型论文:Large Language Models Are Neurosymbolic Reasoners

大语言模型化身符号逻辑大师&#xff0c;AAAI 2024见证文本游戏新纪元 引言&#xff1a;文本游戏中的符号推理挑战 在人工智能的众多应用场景中&#xff0c;符号推理能力的重要性不言而喻。符号推理涉及对符号和逻辑规则的理解与应用&#xff0c;这对于处理现实世界中的符号性…...

服务限流实现方案

服务限流怎么做 限流算法 计数器 每个单位时间能通过的请求数固定&#xff0c;超过阈值直接拒绝。 通过维护一个单位时间内的计数器&#xff0c;每次请求计数器加1&#xff0c;当单位时间内计数器累加到大于设定的阈值&#xff0c;则之后的请求都被绝&#xff0c;直到单位时…...

【RTOS】快速体验FreeRTOS所有常用API(1)工程创建

目录 一、工程创建1.1 新建工程1.2 配置RCC1.3 配置SYS1.4 配置外设1&#xff09;配置 LED PC132&#xff09;配置 串口 UART13&#xff09;配置 OLED I2C1 1.5 配置FreeRTOS1.6 工程设置1.7 生成代码1.8 keil设置下载&复位1.9 添加用户代码 快速体验FreeRTOS所有常用API&a…...

Red Hat Enterprise Linux 8.9 安装图解

风险告知 本人及本篇博文不为任何人及任何行为的任何风险承担责任&#xff0c;图解仅供参考&#xff0c;请悉知&#xff01;本次安装图解是在一个全新的演示环境下进行的&#xff0c;演示环境中没有任何有价值的数据&#xff0c;但这并不代表摆在你面前的环境也是如此。生产环境…...

vcruntime140.dll文件修复的几种常见解决办法,vcruntime140.dll丢失的原因

vcruntime140.dll文件是Windows操作系统中的一个重要动态链接库&#xff08;DLL&#xff09;文件&#xff0c;它是Microsoft Visual C Redistributable的一部分。当出现vcruntime140.dll文件丢失的情况时&#xff0c;可能会导致一些程序无法正常运行或出现错误提示。为了电脑能…...

SpringCloud Alibaba 深入源码 - Nacos 分级存储模型、支撑百万服务注册压力、解决并发读写问题(CopyOnWrite)

目录 一、SpringCloudAlibaba 源码分析 1.1、SpringCloud & SpringCloudAlibaba 常用组件 1.2、Nacos的服务注册表结构是怎样的&#xff1f; 1.2.1、Nacos的分级存储模型&#xff08;理论层&#xff09; 1.2.2、Nacos 源码启动&#xff08;准备工作&#xff09; 1.2.…...

算法训练营Day45

#Java #动态规划 Feeling and experiences&#xff1a; 最长公共子序列&#xff1a;力扣题目链接 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新…...

【Redis漏洞利用总结】

前言 redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。Redis默认使用 6379 端口。 一、redis未授权访问漏洞 0x01 漏洞描述 描述: Redis是一套开源的使用ANSI C编写、支持网络、可基于内存…...

SPI 动态服务发现机制

SPI&#xff08;Service Provier Interface&#xff09;是一种服务发现机制&#xff0c;通过ClassPath下的META—INF/services文件查找文件&#xff0c;自动加载文件中定义的类&#xff0c;再调用forName加载&#xff1b; spi可以很灵活的让接口和实现分离&#xff0c; 让API提…...

【C++进阶07】哈希表and哈希桶

一、哈希概念 顺序结构以及平衡树中 元素关键码与存储位置没有对应关系 因此查找一个元素 必须经过关键码的多次比较 顺序查找时间复杂度为O(N) 平衡树中为树的高度&#xff0c;即O( l o g 2 N log_2 N log2​N) 搜索效率 搜索过程中元素的比较次数 理想的搜索方法&#xff1a…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...