PHP 中的类型杂耍和(严格)大于/小于比较 [英] Type-juggling and (strict) greater/lesser-than comparisons in PHP

查看:27
本文介绍了PHP 中的类型杂耍和(严格)大于/小于比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

PHP 以其类型杂耍而闻名.我必须承认这让我很困惑,而且我很难在比较中找出基本的逻辑/基本事物.

PHP is famous for its type-juggling. I must admit it puzzles me, and I'm having a hard time to find out basic logical/fundamental things in comparisons.

例如:如果 $a >$b 为真且 $b >$c 是真的,这一定意味着 $a >$c总是真的吗?

For example: If $a > $b is true and $b > $c is true, must it mean that $a > $c is always true too?

按照基本逻辑,我会说,但是我很困惑我在这方面并不真正信任 PHP.也许有人可以提供一个例子,但事实并非如此?

Following basic logic, I would say yes however I'm that puzzled I do not really trust PHP in this. Maybe someone can provide an example where this is not the case?

另外我想知道严格小于和严格大于运算符(因为它们的含义被描述为严格的,我过去只从相等比较中知道)如果左操作数和右操作数有什么区别与严格不相等的值交换:

Also I'm wondering with the strict lesser-than and strict greater-than operators (as their meaning is described as strictly which I only knew in the past from the equality comparisons) if it makes any difference if left and right operands are swapped with strictly unequal values:

# Precondition:
if ($a === $b) {
    throw new Exception(
       'Both are strictly equal - can not compare strictly for greater or smaller'
    );
}

($a > $b) !== ($b > $a)

对于大多数类型比较组合,这些更大/更小比较运算符没有记录,所以在这种情况下,阅读手册并没有真正的帮助.

For most of all type comparison combinations these greater / lesser comparison operators are not documented, so reading the manual was not really helpful in this case.

推荐答案

PHP 的比较运算符在几个方面偏离了计算机科学定义:

PHP's comparison operators deviate from the computer-scientific definitions in several ways:

为了构成一个等价关系 == 必须是自反的、对称的和可传递的:

In order to constitute an equivalence relation == has to be reflexive, symmetric and transitive:

  • PHP 的 == 运算符非自反,即 $a == $a 并不总是正确的:

  • PHP's == operator is not reflexive, i.e. $a == $a is not always true:

var_dump(NAN == NAN); // bool(false)

注意:任何涉及NAN 的比较总是false 的事实并非特定于PHP.它由 IEEE 754 浮点运算标准 (更多信息).

Note: The fact that any comparison involving NAN is always false is not specific to PHP. It is mandated by the IEEE 754 Standard for Floating-Point Arithmetic (more info).

PHP 的 == 运算符是对称的,即 $a == $b$b == $ 总是相同的.

PHP's == operator is symmetric, i.e. $a == $b and $b == $a are always the same.

PHP 的 == 运算符不可传递,即来自 $a == $b$b == $c 是否跟随$a == $c:

PHP's == operator is not transitive, i.e. from $a == $b and $b == $c does not follows $a == $c:

var_dump(true == "a"); // bool(true)
var_dump("a" == 0);    // bool(true)
var_dump(true == 0);   // bool(false)

为了构成一个偏序 <=/>= 必须是自反的、反对称的和可传递的:

In order to constitute a partial order <=/>= has to be reflexive, anti-symmetric and transitive:

  • PHP 的 <= 运算符非自反,即 $a <= $a 并不总是正确的(例如与 == 相同).

  • PHP's <= operator is not reflexive, i.e. $a <= $a is not always true (Example same as for ==).

PHP 的 <= 运算符非反对称,即来自 $a <= $b$b <= $a 不遵循 $a == $b:

PHP's <= operator is not anti-symmetric, i.e. from $a <= $b and $b <= $a does not follow $a == $b:

var_dump(NAN <= "foo"); // bool(true)
var_dump("foo" <= NAN); // bool(true)
var_dump(NAN == "foo"); // bool(false)

  • PHP 的 <= 运算符不可传递,即来自 $a <= $b$b <= $c 不跟在 $a <= $c 后面(示例与 == 相同).

  • PHP's <= operator is not transitive, i.e. from $a <= $b and $b <= $c does not follow $a <= $c (Example same as for ==).

    额外:PHP 的 <= 操作符not total,即 $a <= $b>$b <= $a 可以是假的:

    Extra: PHP's <= operator is not total, i.e. both $a <= $b and $b <= $a can be false:

    var_dump(new stdClass <= new DateTime); // bool(false)
    var_dump(new DateTime <= new stdClass); // bool(false)
    

  • 为了构成一个严格偏序 </> 必须是非自反的、不对称的和可传递的:

    In order to constitute a strict partial order </> has to be irreflexive, asymmetric and transitive:

    • PHP 的 < 操作符是非自反的,即 $a <$a 永远不是真的.请注意,这仅适用于 PHP 5.4.以前 INF 评估为 true.

    • PHP's < operator is irreflexive, i.e. $a < $a is never true. Note that this is true only as of PHP 5.4. Previously INF < INF evaluated to true.

    PHP 的 < 操作符非对称,即来自 $a <$b 不遵循 !($b < $a)(与 <= 的示例相同,不是反对称的).

    PHP's < operator is not asymmetric, i.e. from $a < $b does not follow !($b < $a) (Example same as for <= not being anti-symmetric).

    PHP 的 < 运算符不可传递,即来自 $a <$b$b <$c 不跟随 $a <$c:

    PHP's < operator is not transitive, i.e. from $a < $b and $b < $c does not follow $a < $c:

    var_dump(-INF < 0);    // bool(true)
    var_dump(0 < TRUE);    // bool(true)
    var_dump(-INF < TRUE); // bool(false)
    

  • 额外:PHP的<操作符不是三分法,即所有的$a <$b, $b <$a$a == $b 可以为假(示例与 <= 相同,不是总数).

  • Extra: PHP's < operator is not trichotomous, i.e. all of $a < $b, $b < $a and $a == $b can be false (Example same as for <= not being total).

    额外:PHP 的 < 操作符可以是 circular,即 $a <$b, $b <$c$c <$a:

    Extra: PHP's < operator can be circular, i.e. it is possible that $a < $b, $b < $c and $c < $a:

    var_dump(INF < []);           // bool(true)
    var_dump([] < new stdClass);  // bool(true)
    var_dump(new stdClass < INF); // bool(true)
    

    注意:上面的例子抛出了类 stdClass 的对象无法转换为双精度"的通知.

    Note: The above example throws a "Object of class stdClass could not be converted to double" notice.

    您可以在 PHP Sadness 52 - 比较运算符上找到一些关于 PHP 比较运算符的漂亮图表.

    You can find a few nice graphs for PHP's comparison operators on PHP Sadness 52 - Comparison operators.

    作为最后一点,我想指出 PHP 确实保证了两个相等性(与其他几乎所有事物不同).这两个总是成立,仅仅是因为编译器将一个简化为另一个:

    As a last note, I want to point out that there are two equalities that PHP does guarantee (unlike pretty much everything else). These two always hold, simply because the compiler reduces one to the other:

    ($a > $b) == ($b < $a)
    ($a >= $b) == ($b <= $a)
    

    这篇关于PHP 中的类型杂耍和(严格)大于/小于比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆