在尝试模拟一些PHP行为时,我偶然发现了这个:
$a=array(0 => 1, 'test' => 2);
$b=array('test' => 3, 0 => 1);
var_dump($a==$b, $a>$b, $b>$a);
Run Code Online (Sandbox Code Playgroud)
根据输出var_dump $b大于$a.在PHP手册中有一个标准数组比较的转录,它表明数组的值是逐个比较的,如果第二个数组中缺少第一个数组的键,则数组是无法比较的.到现在为止还挺好.但是,如果我尝试这个(仅改变第一个元素$a):
$a=array(0 => 2, 'test' => 2);
$b=array('test' => 3, 0 => 1);
var_dump($a==$b, $a>$b, $b>$a);
Run Code Online (Sandbox Code Playgroud)
所有三个比较结果都是false.这看起来对我来说>是"无法比拟的"(因为结果与结果相同<,而数组也不==是,这没有任何意义),但这不符合PHP手册的转录.这两个键都出现在两个数组中,我希望$a这次更大,因为键0的内容更大$a(2比1).
我试图挖掘到PHP源代码,发现zend_hash_compare()中zend_hash.c,但代码似乎有工作的手册描述.
这里发生了什么?
编辑:正如约阿希姆所示,它处理的是所谓的命令.要偷他的话说:"$ A> $ B遍历B和发现'测试’第一次'测试’是更大$ B所以$ b大于它返回false $ B> $一个环比和认定". 0'首先.'0'在$ a中更大,所以$ a更大,它返回false."
- 原帖 -
我不是百分百肯定我是对的; 我之前没有见过这个,并且只是简单地研究了一下(顺便说一下,在一个很好的问题上,主要的荣誉!).无论如何,看起来PHP文档是错误的,或者这是一个错误(在这种情况下你可能想要提交它),这就是原因:
在zend_hash_compare()中zend_hash.c,却仿佛有什么过一些混乱ordered的(我看行1514和1552-1561,这是我最好的猜测是哪里出了问题,没有做大量的测试).
这就是我的意思; 试试这个:
$a=array(0 => 2, 'test' => 2);
$b=array(0 => 1, 'test' => 3);
var_dump($a==$b, $a>$b, $b>$a);
Run Code Online (Sandbox Code Playgroud)
注意我只是切换索引的顺序,然后$a>$b返回true.另见:
$x=array(0 => 2, 'test' => 2);
$y = $x;
$y[0] = 1; $y['test'] = 3;
var_dump($x==$y, $x>$y, $y>$x);
Run Code Online (Sandbox Code Playgroud)
另请注意,$x>$y返回true.换句话说,PHP 不只是匹配数组键!它关心数组中这些键的顺序!您可以通过修改之前拿出一个"基地"阵列和"复制"成新的变量(在我的X/Y为例)防止这种情况发生,或者您可以创建一个对象,如果你愿意的话.
换句话说,更简单地说,似乎PHP不只是查看键值,而是键值和键顺序.
再次,我要强调,我不知道这是否预期的行为(它看起来像的东西,他们应该在PHP手册上注明,如果确实如此),或一个bug /错误的/ etc(这似乎更容易对我来说).但无论哪种方式,我发现,它首先由键(行数相比1496-1501中zend_hash.c),然后通过两个键值和按键的顺序.
似乎比较循环是在>右手阵列上完成的情况下,并且在<完成左手阵列的情况下,即总是在所谓的"较小"阵列上.元素的顺序是重要的,因为转录代码中的foreach循环遵循数组顺序.
换一种说法;
$ a> $ b遍历b并首先找到'test'.'test'在$ b中更大,所以$ b更大,它返回false.
$ b> $ a循环a并首先找到'0'.'$'在$ a中更大,所以$ a更大并返回false.
这实际上是有意义的,然后允许"更大"的数组包含"较小"数组不包含的元素,并且只要所有公共元素都更大,它们仍然更大.