在尝试模拟一些PHP行为时,我偶然发现了这个:
$a=array(0 => 1, 'test' => 2);
$b=array('test' => 3, 0 => 1);
var_dump($a==$b, $a>$b, $b>$a);
根据var_dump
$b
的输出大于$a
。在PHP手册中有一个Transcription of standard array comparison,它表明数组的值是逐个比较的,如果第二个数组中缺少第一个数组的键,则数组是无法比较的。到现在为止还挺好。但是,如果我尝试这个(仅改变$a
的第一个元素):
$a=array(0 => 2, 'test' => 2);
$b=array('test' => 3, 0 => 1);
var_dump($a==$b, $a>$b, $b>$a);
所有三个比较结果均为false
。对我来说这看起来像“无法比拟”(因为>
结果与<
结果相同,而数组也不是==
,这没有意义)但这不是适合PHP手册的转录。这两个键都存在于两个数组中,我希望此次$a
更大,因为键{0的内容在$a
中更大(2对1)。
我试图深入研究PHP源代码,并在zend_hash.c
中找到了zend_hash_compare(),但其中的代码似乎与手册中描述的一样。
这里发生了什么?
答案 0 :(得分:6)
编辑:正如约阿希姆所示,它处理了所谓的订单。窃取他的话: “$ a&gt; $ b在b上循环并首先找到'test'。'test'在$ b中更大,所以$ b更大并返回false。$ b&gt; $ a循环a并首先找到'0'。 0'在$ a中更大,所以$ a更大,它返回false。“
- 原帖 -
我不是百分百肯定我是对的;我之前没有见过这个,并且只是简单地研究了一下(顺便说一下,在一个很好的问题上,主要的荣誉!)。无论如何,看起来PHP文档是错误的,或者这是一个错误(在这种情况下你可能想提交它),这就是原因:
在zend_hash_compare()
的{{1}}中的,似乎对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);
返回$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);
返回true。换句话说,PHP 不只是匹配数组键!它关心数组中这些键的顺序!您可以通过提出“基础”数组并在修改之前将其“复制”到新变量(在我的x / y示例中)来防止这种情况,或者如果您愿意,可以创建一个对象。
换句话说,更简单地说,似乎PHP不只是查看键值,而是键值和键顺序。
同样,我强调我不知道这种预期的行为(它似乎是他们应该在PHP手册中注意到的东西),或者是错误/错误/等(这似乎对我来说更有可能) )。但无论哪种方式,我发现它首先按键数($x>$y
中的行1496-1501
)进行比较,然后按键值和键顺序进行比较。
答案 1 :(得分:5)
似乎比较循环是在&gt;的情况下。在右手阵列上完成并且在&lt;在左手阵列上完成,即总是在所谓的“较小”阵列上。元素的顺序很重要,因为转录代码中的foreach循环遵循数组顺序。
换句话说;
$ a&gt; $ b遍历b并首先找到'test'。 'test'在$ b中更大,所以$ b更大,它返回false。
$ b&gt; $ a循环a并首先找到'0'。 “$”在$ a中更大,因此$ a更大,并返回false。
这实际上是有意义的,然后允许“更大”的数组包含“较小”数组不包含的元素,并且只要所有公共元素都更大,它们仍然更大。
答案 2 :(得分:-1)
我认为这里是逐一比较$a[0]>$b[0]
但$a['test']<$b['test']
。
你不能说哪个数组更大。