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

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

问题描述

PHP以其类型的杂耍而闻名。我必须承认它困惑我,我很难在比较中找出基本的逻辑/基本的东西。



例如:如果 $ a> $ b 为true, $ b> $ c 是真的,这意味着 $ a>



根据基本逻辑,我会说 >但是我很困惑,我真的不相信PHP在这。也许有人可以提供一个例子,这不是这种情况?



我也想知道与严格小于和严格大于运算符如果左和右操作数与严格不等的值交换,它会产生任何不同:

 #前提条件:
if($ a === $ b){
throw new Exception(
'两者都严格相等 - 不能严格比较大或小'
);
}

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

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

解决方案

PHP的比较运算符偏离计算机科学定义:



为了构成等价关系 == 必须是反身,对称和可传递的:





构成部分命令 <= / > = 必须是反身,反对称和传递:




  • PHP < = strong>不反思,即 $ a <= a a 并不总是真实( ==


  • PHP的< = 运算符不是反对称,即从 $ a< = $ b $ b< = $ a $ a == $ b

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

    code>运算符不可传递,即从 $ a <= $ b $ b < = $ c 不跟随 $ a <= $ c (示例与 ==


  • 额外:PHP的< = 运算符 / strong>,即 $ a <= b $ $ b <= a a

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




构成严格部分顺序 / > 必须是无反射, transitive:




  • PHP < 运算符 irreflexive ,即 $ a< $ a 永远不是真的。请注意,这是真实的只有PHP 5.4 。以前 INF <

    PHP < 运算符不对称,即 $ a< $ b 不跟随!($ b <$ a)(示例与< = 不是反对称的)。


  • PHP的< >不可传递,即从 $ a< $ b $ b < $ c 不遵循 $ a< $ c

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


  • Extra:PHP / code>运算符不是三分类,即 $ a < $ b $ b< $ a $ a == $ b 可以为false(示例与< = 不是总计。)


  • 额外:PHP的< 循环,即可能 $ a < $ b $ b< $ c $ c < $ a

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



    注意:上面的例子抛出一个stdClass类的对象不能




您可以在 PHP悲伤52 - 比较运算符



最后一点,我想点有两个平等PHP 保证(不同于其他一切)。这两个总是保持,只是因为编译器把一个减少到另一个:

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


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.

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

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'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's == operator is not reflexive, i.e. $a == $a is not always true:

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

    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's == operator is symmetric, i.e. $a == $b and $b == $a are always the same.

  • 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's <= operator is not reflexive, i.e. $a <= $a is not always true (Example same as for ==).

  • 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's <= operator is not transitive, i.e. from $a <= $b and $b <= $c does not follow $a <= $c (Example same as for ==).

  • 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'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's < operator is not asymmetric, i.e. from $a < $b does not follow !($b < $a) (Example same as for <= not being anti-symmetric).

  • 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)
    

  • 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).

  • 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)
    

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

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

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天全站免登陆