第一个例子:
$x = array("a" => 1, "b" => 2);
$y = array("b" => 1, "a" => 2);
$xLessY = ($x < $y);
$xGreaterY = ($x > $y);
var_dump($xLessY, $xGreaterY);
结果:$ xLessY = true ,$ xGreaterY = true
第二个例子:
$x = array("a" => 2, "b" => 1);
$y = array("b" => 2, "a" => 1);
$xLessY = ($x < $y);
$xGreaterY = ($x > $y);
var_dump($xLessY, $xGreaterY);
结果:$ xLessY = false ,$ xGreaterY = false
根据http://docs.php.net/manual/en/language.operators.comparison.php的文件:
如果找不到操作数1的键 操作数2然后是数组 无法比拟,否则 - 比较 价值值
在我们的例子中,数组$ x中的每个键都存在于数组$ y中,因此$ x和$ y是可比较的。 另请参阅文档中的示例:
// Arrays are compared like this with standard comparison operators
function standard_array_compare($op1, $op2)
{
if (count($op1) < count($op2)) {
return -1; // $op1 < $op2
} elseif (count($op1) > count($op2)) {
return 1; // $op1 > $op2
}
foreach ($op1 as $key => $val) {
if (!array_key_exists($key, $op2)) {
return null; // uncomparable
} elseif ($val < $op2[$key]) {
return -1;
} elseif ($val > $op2[$key]) {
return 1;
}
}
return 0; // $op1 == $op2
}
这种行为非常奇怪:$ x小于$ y,同时$ x大于$ y(第一个例子),两个数组相当。
我认为这是因为php始终从符号'&lt;'的一个明确方面开始比较。我的意思是:for($ x&lt; $ y)php将$ x作为操作数1,对于($ x&gt; $ y),它需要$ y作为操作数1.虽然我在文档中没有找到任何关于此行为的信息。
你对此有何看法?
答案 0 :(得分:1)
你的假设是正确的。 >
运算符被解析为
| expr '>' expr { zend_do_binary_op(ZEND_IS_SMALLER, &$$, &$3, &$1 TSRMLS_CC); }
这基本上说,X > Y
相当于not X < Y
,当比较不可交换时,这当然是错误的。考虑在bugs.php.net上报告此内容。
答案 1 :(得分:1)
我不会说$x > $y
替换$y < $x
的错误。
当然,如果您在传递给比较函数时参数没有交换位置的方式实现$x > $y
,您将解决此特定问题。但是你会得到另一个回报。
现在你有:
$x < $y <=> cmp($x, $y) == -1
$x > $y <=> cmp($y, $x) == -1
因为第一个参数的第一个键始终首先进行比较,所以如果reset($x) < $y[key($x)]
和reset($y) < $x[key($y)]
,则两个条件都为真。
但考虑另一种可以解决这个问题的实现:
$x < $y <=> cmp($x, $y) == -1
$x > $y <=> cmp($x, $y) == +1
当操作数的顺序固定时,<
和>
是一致的,但是当我们交换操作数时,我们现在会得到奇怪的行为,因为我们仍然可以cmp($x, $y) == -1
和{{ 1}},这意味着cmp($y, $x) == -1
和$x < $y
都是真的。
总之,唯一的解决方案是修复比较函数,使其行为是反对称的,即$y < $x
,至少在声称具有可比性的一组元素中。{/ p>
答案 2 :(得分:0)
我可能错了,但我认为你不能用这种方式比较数组。我一直认为可以检查是否存在相等或不平等,但不能将数量与&lt;和&gt;。
man page on array operators似乎证实了这一点。