比较PHP中的数组 - 有趣的行为

时间:2011-06-25 20:34:01

标签: php arrays compare

第一个例子:

$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.虽然我在文档中没有找到任何关于此行为的信息。
你对此有何看法?

3 个答案:

答案 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似乎证实了这一点。