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

这篇具有很好参考价值的文章主要介绍了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);

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

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

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

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

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

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

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

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

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

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

/* {{{ 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);
}
/* }}} */

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

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

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

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

相关文档:

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

3、源码地址 :GitCode - 开发者的代码家园 文章来源地址https://www.toymoban.com/news/detail-807388.html

到了这里,关于php array_diff 比较两个数组bug避坑 深入了解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • php 两个数组取交集、并集、差集

    php 两个数组取交集、并集、差集 交集:array_intersect() 并集:array_merge() 差集:array_diff() laravel 两个集合取交集、并集、差集 交集: 使用intersect()函数,用于获取两个集合的交集: 并集:使用union()函数,用于获取两个集合的并集: 差集:使用diff()函数,用于获取两个集合的

    2024年02月12日
    浏览(32)
  • vue diff 双端比较算法

    使用四个变量 oldStartIdx、oldEndIdx、newStartIdx 以及 newEndIdx 分别存储旧 children 和新 children 的两个端点的位置索引 除了位置索引之外,还需要拿到四个位置索引所指向的 VNode 使用旧 children 的头一个 VNode 与新 children 的头一个 VNode 比对,即 oldStartVNode 和 newStartVNode 比较对。 使用

    2024年02月14日
    浏览(31)
  • Linux 系统 diff 文件比较命令详解

    diff 命令用于比较两个文件或目录之间的差异。它会逐行比较文件的内容,并且在不同的行上显示不同之处。下面是 diff 命令的使用方法和选项: 基本语法: 常见选项: -c 或 --context :显示上下文差异(默认为 3 行) -u 或 --unified :显示统一格式的差异 -r 或 --recursive :递归

    2024年02月11日
    浏览(33)
  • linux文件比较工具diff-关于参数-pN的设置方法

    非纯文本文件比较可用cmp命令 第一:利用diff创建分析文件,处理补丁(patch)功能的文件 案例:多数用于同一软件的不同版本之间,比如比较配置文件和源文件的区别,生成补丁文件,执行更新,或者恢复操作 以’行‘为单位进行比较,多数用在同一文件新旧版本的比较上

    2024年01月19日
    浏览(37)
  • Docker中,diff和merged这两个文件夹的作用

    在Docker中, diff 和 merged 这两个文件夹都是与容器的文件系统相关的。它们的作用分别是: 1. diff 文件夹 diff 文件夹包含了容器文件系统的改变。每当您向容器中添加、删除或修改文件时, diff 文件夹中都会生成相应的增量改变。因此, diff 文件夹记录了容器文件系统的修改

    2024年02月12日
    浏览(82)
  • 差异对比犀利手册:使用 Partial Diff 插件在 VSCode 中比较代码差异

    简介: 在本教程中,我们将介绍如何在 Visual Studio Code(VSCode)编辑器中安装和使用 Partial Diff 插件来进行源代码文件的差异比较。Partial Diff 插件是一个强大且简单的工具,可以帮助你更容易地查看和理解代码的变化。在本教程中,我们将带你从头开始,一步一步地进行安装

    2024年02月05日
    浏览(29)
  • 避坑宝典|win11升级最新预览体验版bug梳理

    如果看到这篇文章你的系统还没升级,不妨先看看已升级Win11的用户反馈和我本人遇到的坑,少走弯路,减少NG时间。 一、亲测win11升级的前世今生。 本次测试升级途径: 加入“windows预览体验计划”,通过dev通道升级; 本次测试升级过程: 加入“用户预览体验计划”后,

    2024年02月10日
    浏览(33)
  • git diff两个分支有差异git merge却显示没有可以合并的内容

    problem: 用git diff可以发现两个分支还是有很多不一样的地方,可用git merge显示not something we can merge 输入gitk查看,发现preview已经在这个分支前面了。。。虽然不太懂,但这样是没办法将preview合并当前分支的,只能这个分支合并preview。。。 解决:因为也不会别的解决方法,因

    2024年02月12日
    浏览(37)
  • 高级两路和三路文件比较(diff)、合并和文件夹同步——Araxis Merge介绍

      0 1、对于法律和出版专业人士 立即识别不同合同或手稿草稿之间的每一个变化。直接打开和比较来自Microsoft Office(Word 和 Excel)、OpenDocument、 PDF和RTF文件的文本。从其他应用程序(如 Microsoft Word)复制文本并将其直接粘贴到文本比较中。 0 2、对于软件工程师和网络开发人

    2024年02月08日
    浏览(35)
  • 【STM32】HAL库UART含校验位的串口通信配置BUG避坑

    【STM32】HAL库UART含校验位的串口通信配置BUG避坑 UART通过一条线就能完成数据的发送 另外一条线则完成数据的接收 所以一共是两条线 TX RX UART在空闲时为低电平 时钟周期由波特率确定 通常是115200bit/s UART协议由四个部分组成: 起始位: 固定低电平 1个时钟周期 数据域: 通常

    2024年01月20日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包