【问题标题】:Are all PHP equality comparisons symmetric?所有 PHP 相等比较都是对称的吗?
【发布时间】:2011-06-12 18:16:01
【问题描述】:

$a == $b 是否总是等同于 $b == $a

我认为在 JavaScript 中存在一些奇怪的情况,但由于强制转换,这是不正确的。

我认为ide 是正确的。我再问问question

【问题讨论】:

  • 我会说“反身”。
  • @Joe 是正确的。这被认为是自反性。关联性是当(A + B) + C = A + (B + C)
  • 不要引用我的话,但我认为传递性会出现奇怪的情况;即a == bb == ca != c
  • 我尝试了多种变体,找不到($a == $b) !== ($b == $a)的案例,但我现在决心这样做!
  • 这不是反身性——这是对称性!自反性是$a == $a!

标签: php comparison equals-operator


【解决方案1】:

简而言之,是的。 $a == $b 将始终等同于 $b == $a。有一些缺点,例如花车。当然,无论如何你都不应该嵌套两个浮点数来实现相等。

编辑
关于浮点数:如果你有两个浮点数并比较它们,它们在技术上应该是相同的。但是,看起来具有相同值的浮点值实际上并不需要相同。因此,如果$a 是文字.69$b 是计算结果,那么它们很可能不同,但都显示相同的值。这就是为什么您永远不应该使用 == 比较浮点值。

如果您需要比较浮点值,您确实需要在特定情况下使用可接受的最小差异。像这样的东西可以用于比较浮点数(将我们可接受的最小差异设置为0.000001):

if(abs($a-$b) < 0.000001) {
  //Same
}

PHP: abs - Absolute Value

【讨论】:

  • 你能举一个例子说明浮点数在哪里比较相等,但不是另一种?我了解浮点数导致的舍入误差,但不应该在任一方向上进行一致的比较吗?
  • 我已经更新了我的答案以包含更多关于浮点比较的信息。我希望它有所帮助。
  • 不,它没有:) 这有点无关。不过还是谢谢。
【解决方案2】:

我能看到的唯一不同的类型是:

$foo = 1;
$bar = 1;

($foo = $foo + $bar) == ($bar = $foo);

要知道为什么,看看它

A -> ($foo = $foo + $bar)
B -> ($bar = $foo);

如果先运行A,则结果为2B的结果为2,所以它们相等,测试为true

如果先运行B,则结果为1B的结果为2,所以它们不相等,测试为false

但是对于任何单一类型的比较(其中A 是一个变量而不是一个表达式),它将始终是自反的。

所以在一般意义上,A == B 并不总是 100% 保证等于 B == A。对于变量,它总是等价的。但对于涉及变量赋值或修改的复杂表达式,它可能不是。

【讨论】:

    【解决方案3】:

    取决于这两个调用之间发生的情况。否则,是的,它们是相同的。顺序没有区别。使用 2 等于 == 1 的字符串和 1 的整数,比较时将返回 true。类型被忽略,只比较值。所以没有奇怪。

    http://php.net/manual/en/language.operators.comparison.php

    <?
    
    $a=(string) 1;
    $b=(int) 1;
    
    var_dump($a);
    var_dump($b);
    
    
    echo $a==$b;
    

    输出:1

    http://www.ideone.com/JLJWQ

    编辑

    澄清一下,您绝对不能在 $a 或 $b 中添加任何内容来获得不同的比较输出,只需将其放在运算符的另一侧即可。

    $a="1234";
    $b="1234";
    
    echo $a==$b;
    echo $b==$a;
    

    对于任何 $a 或 $b 值,其输出将毫无疑问始终为真或假。

    【讨论】:

    • 是的,但这是一个简单的例子。我想也许有一些奇怪的情况,比如"01" == 1 1 可能会被转换为字符串,然后它们不相等,但在1 == "01" 中,字符串会被转换为 int,然后它们就会相等。我知道情况并非如此。 php.net/manual/en/… 但也许有一些我不知道的奇怪的。
    • 好吧.. cmets 中提到了一种奇怪的东西。它带有数字字符串。但正如预期的那样。即使在这种情况下,运营商的每一方都处于开启状态,这无关紧要。 ideone.com/UHD43
    • 是的...这很奇怪,但至少它已被记录在案。接受这个答案是确定的。
    【解决方案4】:

    http://php.net/manual/en/language.operators.comparison.php

    如果您想在比较中考虑类型转换,可以使用不同的运算符。 == 在相等的值上评估为真,但不比较数据类型。当值和数据类型相等时,=== 评估为真。使用后者考虑类型转换,它通常会被忽略(例如:表示整数的字符串和正在比较的整数。)

    条件中的逻辑顺序不应该有区别。

    【讨论】:

    • 我不喜欢你使用“应该”这个词。希望有一个明确的答案:)
    【解决方案5】:

    我尝试了多种变体,但找不到 ($a == $b) !== ($b == $a) 的情况,但到目前为止都没有奏效:

    <?php
    
    $a = 0;
    $b = "0";
    
    echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";
    
    $a = 0;
    $b = NULL;
    
    echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";
    
    $a = 0;
    $b = false;
    
    echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";
    
    $a = false;
    $b = NULL;
    
    echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";
    
    $a = "";
    $b = NULL;
    
    echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";
    
    $a = "NULL";
    $b = NULL;
    
    echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";
    
    $a = 0.000000000000000000000000001;
    $b = 0;
    
    echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";
    
    $a = array();
    $b = array();
    
    echo (($a == $b) == ($b == $a)) ? "OK\n" : "FAIL\n";
    

    所以,我在这一点上放弃了。欢迎提出想法!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多