当前位置: 首页 > 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…...

DIY红外遥控电视关机器:从ATTINY85到晶体管驱动的硬件实践

1. 项目概述&#xff1a;从“关不掉”的烦恼到“一键清静”的实践不知道你有没有过这样的经历&#xff1a;在餐厅吃饭&#xff0c;墙上挂着的电视正播放着吵闹的广告&#xff1b;在候车室&#xff0c;多台电视同时播放着不同的节目&#xff0c;让人心烦意乱。你只想安安静静地待…...

信号处理避坑指南:ESPRIT、Root-Music等DOA估计算法,到底该怎么选?

DOA估计算法选型实战&#xff1a;ESPRIT与MUSIC家族的性能对决 当八通道均匀线阵捕捉到两个间隔仅5的远场信号时&#xff0c;算法A在信噪比15dB时成功分离目标&#xff0c;而算法B直到25dB才能勉强分辨——这种真实场景中的性能差异&#xff0c;正是工程师选择DOA&#xff08;波…...

Linux密钥文件管理实战指南

Linux密钥文件管理实战指南本文面向具备一定 Linux 基础的技术人员&#xff0c;围绕密钥文件管理展开&#xff0c;重点讨论敏感文件权限、轮换流程和审计追踪。在中级运维和系统管理工作中&#xff0c;这类主题常常与配置变更、资源状态、权限边界、自动化任务和业务影响交织在…...

NotebookLM权限审计日志难追溯?手把手教你启用VPC Service Controls + Cloud Logging Query Builder构建实时越权预警看板

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;NotebookLM权限控制设置 NotebookLM 是 Google 推出的基于用户上传文档进行 AI 辅助理解与生成的实验性工具&#xff0c;其权限模型默认采用 Google 账户体系集成&#xff0c;但需主动配置以满足团队协…...

NTN 长距离通信领域亮相

核心蜂窝解决方案亮相并带来Nordic NTN 核心解决方案深度分享。环节将全面解析 nRF9151 模组的核心特性与技术优势&#xff0c;详解卫星星座生态布局及 nRFCloud 平台的应用价值&#xff0c;为参会者勾勒 NTN 技术的整体框架与商业落地前景&#xff0c;为后续内容奠定专业基础。…...

避坑指南:LVGL Bar控件在RTOS和低内存MCU上的5个常见问题与解决方案

避坑指南&#xff1a;LVGL Bar控件在RTOS和低内存MCU上的5个常见问题与解决方案 在嵌入式开发中&#xff0c;LVGL作为轻量级图形库被广泛应用&#xff0c;但其Bar控件&#xff08;进度条&#xff09;在资源受限环境&#xff08;如FreeRTOS、内存<64KB的MCU&#xff09;下常出…...

STM32与PS2手柄的无线交互:从硬件对接到按键解析

1. 认识PS2手柄与STM32的无线交互 第一次接触PS2手柄和STM32的对接时&#xff0c;我完全被这个经典游戏手柄的通信协议吸引了。你可能不知道&#xff0c;这个2000年推出的手柄至今仍在嵌入式领域发光发热&#xff0c;主要得益于它简单的通信协议和稳定的性能。我实测过市面上常…...

STM32H7网络延迟问题分析与解决方案

1. 问题现象与背景分析最近在将STM32H7系列设备的DFP&#xff08;Device Family Pack&#xff09;从v2.2.0升级到v2.3.0版本后&#xff0c;不少开发者反馈网络数据传输出现了明显的延迟问题。通过简单的ping测试可以直观观察到&#xff0c;使用v2.3.0版本的往返时间(RTT)相比v2…...

SillyTavern角色卡片系统:从图片到智能伙伴的魔法之旅

SillyTavern角色卡片系统&#xff1a;从图片到智能伙伴的魔法之旅 【免费下载链接】SillyTavern LLM Frontend for Power Users. 项目地址: https://gitcode.com/GitHub_Trending/si/SillyTavern 你是否曾想过&#xff0c;一张普通的图片如何能变成一个会思考、会对话、…...

别再死记硬背了!PADS Logic/Layout/Router这三个界面,到底该怎么分工协作?

PADS三剑客协作指南&#xff1a;从原理图到PCB的高效设计流 在电子设计自动化&#xff08;EDA&#xff09;领域&#xff0c;Mentor Graphics&#xff08;现为Siemens EDA&#xff09;的PADS系列工具以其专业性和高效性著称。然而&#xff0c;许多初学者常陷入一个误区——将PAD…...