Type-juggling and (strict) greater/lesser-than comparisons in 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.

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.

15306 次浏览

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

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

  • PHP 的 ==操作符是 不是条件反射,也就是说 $a == $a并不总是正确的:

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

    注意: 任何涉及 NAN的比较总是 false这一事实并不是 PHP 特有的。它是由 IEEE 754浮点运算标准(more info)规定的。

  • PHP 的 ==操作符是 对称的,即 $a == $b$b == $a总是相同的。

  • PHP 的 ==运算符是 不是传递性的,即从 $a == $b$b == $c没有跟随 $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)
    

    注意: 上面的例子抛出了一个“ Object of class stdClass could not be turn to double”通知。

您可以在 PHP Sadness 52 - Comparison operators上找到一些 PHP 比较运算符的漂亮图表。

最后一点,我想指出 PHP 是的保证了两个等式(不像其他任何东西)。这两者总是成立,仅仅是因为编译器将其中一个简化为另一个:

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

在 PHP (由 PHP 5.6.14至少)中有 no 完全相同比较运算符(>==<==) ,但在检查更大/更小之前有几种方法可以检查 enforce a strict type check:

  1. if (gettype($a) === gettype($b))检查两种变量类型
  2. 强制你所需要的类型铸造例如
  3. 强迫你所需要的类型杂耍例如

请注意:

  • 浮点精度 是有限的
  • INFNAN下属于 float
  • 一些 无穷无尽等于另一些 无穷无尽(从 PHP 5.4开始)
  • 科学记数法总是属于 float型,即使数字很小,也从不属于 integer
  • 超过 PHP_INT_MAX的整数会自动转换为 float
  • Floats over system's boundaries get the INF value
  • 未定义的变量的类型和值为 NULL
  • 0前面的整数将从八进制转换为十进制(按约定)
  • 转换包含带有前导 0 to整数的整数的字符串将前导 0去掉

一些奇异的比较:

Very strange:
$a      VS.     $b         $a>$b   $a<$b   $a<=$b  $a>=$b  $a==$b  $a===$b
float(NAN)    float(-INF)     false   false   false   false   false   false
float(NAN)      float(0)      false   false   false   false   false   false
float(NAN)      float(1)      false   false   false   false   false   false
float(NAN)     float(INF)     false   false   false   false   false   false
float(NAN)     float(NAN)     false   false   false   false   false   false
float(NAN)      int(-1)       false   false   false   false   false   false
float(NAN)       int(0)       false   false   false   false   false   false
float(NAN)       int(1)       false   false   false   false   false   false

相等但不完全相同:

$a      VS.     $b         $a>$b   $a<$b   $a<=$b  $a>=$b  $a==$b  $a===$b
NULL(NULL)      array()       false   false    true    true    true   false
NULL(NULL)    bool(false)     false   false    true    true    true   false
NULL(NULL)      float(0)      false   false    true    true    true   false
NULL(NULL)       int(0)       false   false    true    true    true   false
NULL(NULL)      str('')       false   false    true    true    true   false
array()      bool(false)     false   false    true    true    true   false
bool(false)      float(0)      false   false    true    true    true   false
bool(false)       int(0)       false   false    true    true    true   false
str('')      bool(false)     false   false    true    true    true   false
bool(false)      str('0')      false   false    true    true    true   false
float(-INF)     bool(true)     false   false    true    true    true   false
bool(true)      float(1)      false   false    true    true    true   false
float(INF)     bool(true)     false   false    true    true    true   false
float(NAN)     bool(true)     false   false    true    true    true   false
bool(true)      int(-1)       false   false    true    true    true   false
bool(true)       int(1)       false   false    true    true    true   false
bool(true)     str("\0")      false   false    true    true    true   false
bool(true)      str('+')      false   false    true    true    true   false
bool(true)      str('-')      false   false    true    true    true   false
bool(true)     str('01')      false   false    true    true    true   false
bool(true)      str('1')      false   false    true    true    true   false
bool(true)    str('false')    false   false    true    true    true   false
str('text')     bool(true)     false   false    true    true    true   false
str('true')     bool(true)     false   false    true    true    true   false
    int(0)        float(0)      false   false    true    true    true   false
str("\0")       float(0)      false   false    true    true    true   false
str('')        float(0)      false   false    true    true    true   false
str('+')       float(0)      false   false    true    true    true   false
str('-')       float(0)      false   false    true    true    true   false
str('0')       float(0)      false   false    true    true    true   false
str('false')     float(0)      false   false    true    true    true   false
str('text')      float(0)      false   false    true    true    true   false
str('true')      float(0)      false   false    true    true    true   false
int(1)        float(1)      false   false    true    true    true   false
float(1)      str('01')      false   false    true    true    true   false
float(1)       str('1')      false   false    true    true    true   false
str("\0")        int(0)       false   false    true    true    true   false
str('')         int(0)       false   false    true    true    true   false
str('+')        int(0)       false   false    true    true    true   false
str('-')        int(0)       false   false    true    true    true   false
int(0)        str('0')      false   false    true    true    true   false
str('false')      int(0)       false   false    true    true    true   false
str('text')       int(0)       false   false    true    true    true   false
str('true')       int(0)       false   false    true    true    true   false
int(1)       str('01')      false   false    true    true    true   false
int(1)        str('1')      false   false    true    true    true   false
str('1')      str('01')      false   false    true    true    true   false

同时降低和提高?

$a      VS.     $b         $a>$b   $a<$b   $a<=$b  $a>=$b  $a==$b  $a===$b
float(NAN)     str("\0")       true    true    true    true   false   false
float(NAN)      str('')        true    true    true    true   false   false
float(NAN)      str('+')       true    true    true    true   false   false
float(NAN)      str('-')       true    true    true    true   false   false
float(NAN)      str('0')       true    true    true    true   false   false
float(NAN)     str('01')       true    true    true    true   false   false
float(NAN)      str('1')       true    true    true    true   false   false
float(NAN)    str('false')     true    true    true    true   false   false
float(NAN)    str('text')      true    true    true    true   false   false
float(NAN)    str('true')      true    true    true    true   false   false

平等且相同:

$a      VS.     $b         $a>$b   $a<$b   $a<=$b  $a>=$b  $a==$b  $a===$b
NULL(NULL)     NULL(NULL)     false   false    true    true    true    true
float(-INF)    float(-INF)     false   false    true    true    true    true
float(INF)     float(INF)     false   false    true    true    true    true

较低或较高:

$a      VS.     $b         $a>$b   $a<$b   $a<=$b  $a>=$b  $a==$b  $a===$b
NULL(NULL)     bool(true)     false    true    true   false   false   false
float(-INF)     NULL(NULL)      true   false   false    true   false   false
NULL(NULL)      float(1)      false    true    true   false   false   false
float(INF)     NULL(NULL)      true   false   false    true   false   false
float(NAN)     NULL(NULL)      true   false   false    true   false   false
NULL(NULL)      int(-1)       false    true    true   false   false   false
NULL(NULL)       int(1)       false    true    true   false   false   false
NULL(NULL)     str("\0")      false    true    true   false   false   false
NULL(NULL)      str('+')      false    true    true   false   false   false
NULL(NULL)      str('-')      false    true    true   false   false   false
NULL(NULL)      str('0')      false    true    true   false   false   false
NULL(NULL)     str('01')      false    true    true   false   false   false
NULL(NULL)      str('1')      false    true    true   false   false   false
NULL(NULL)    str('false')    false    true    true   false   false   false
NULL(NULL)    str('text')     false    true    true   false   false   false
NULL(NULL)    str('true')     false    true    true   false   false   false
   array()       bool(true)     false    true    true   false   false   false
float(-INF)      array()       false    true    true   false   false   false
array()        float(0)       true   false   false    true   false   false
array()        float(1)       true   false   false    true   false   false
float(INF)      array()       false    true    true   false   false   false
float(NAN)      array()       false    true    true   false   false   false
array()        int(-1)        true   false   false    true   false   false
array()         int(0)        true   false   false    true   false   false
array()         int(1)        true   false   false    true   false   false
array()       str("\0")       true   false   false    true   false   false
str('')        array()       false    true    true   false   false   false
array()        str('+')       true   false   false    true   false   false
array()        str('-')       true   false   false    true   false   false
array()        str('0')       true   false   false    true   false   false
array()       str('01')       true   false   false    true   false   false
array()        str('1')       true   false   false    true   false   false
array()      str('false')     true   false   false    true   false   false
array()      str('text')      true   false   false    true   false   false
array()      str('true')      true   false   false    true   false   false
  bool(true)    bool(false)      true   false   false    true   false   false
float(-INF)    bool(false)      true   false   false    true   false   false
float(1)     bool(false)      true   false   false    true   false   false
float(INF)    bool(false)      true   false   false    true   false   false
float(NAN)    bool(false)      true   false   false    true   false   false
bool(false)      int(-1)       false    true    true   false   false   false
int(1)      bool(false)      true   false   false    true   false   false
bool(false)     str("\0")      false    true    true   false   false   false
bool(false)      str('+')      false    true    true   false   false   false
bool(false)      str('-')      false    true    true   false   false   false
bool(false)     str('01')      false    true    true   false   false   false
str('1')     bool(false)      true   false   false    true   false   false
bool(false)    str('false')    false    true    true   false   false   false
str('text')    bool(false)      true   false   false    true   false   false
str('true')    bool(false)      true   false   false    true   false   false
bool(true)      float(0)       true   false   false    true   false   false
bool(true)       int(0)        true   false   false    true   false   false
str('')       bool(true)     false    true    true   false   false   false
bool(true)      str('0')       true   false   false    true   false   false
float(-INF)      float(0)      false    true    true   false   false   false
float(-INF)      float(1)      false    true    true   false   false   false
float(INF)    float(-INF)      true   false   false    true   false   false
float(-INF)      int(-1)       false    true    true   false   false   false
float(-INF)       int(0)       false    true    true   false   false   false
float(-INF)       int(1)       false    true    true   false   false   false
float(-INF)     str("\0")      false    true    true   false   false   false
float(-INF)      str('')       false    true    true   false   false   false
float(-INF)      str('+')      false    true    true   false   false   false
float(-INF)      str('-')      false    true    true   false   false   false
float(-INF)      str('0')      false    true    true   false   false   false
float(-INF)     str('01')      false    true    true   false   false   false
float(-INF)      str('1')      false    true    true   false   false   false
float(-INF)    str('false')    false    true    true   false   false   false
float(-INF)    str('text')     false    true    true   false   false   false
float(-INF)    str('true')     false    true    true   false   false   false
float(1)       float(0)       true   false   false    true   false   false
float(INF)      float(0)       true   false   false    true   false   false
float(0)       int(-1)        true   false   false    true   false   false
int(1)        float(0)       true   false   false    true   false   false
float(0)      str('01')      false    true    true   false   false   false
str('1')       float(0)       true   false   false    true   false   false
float(INF)      float(1)       true   false   false    true   false   false
float(1)       int(-1)        true   false   false    true   false   false
float(1)        int(0)        true   false   false    true   false   false
float(1)      str("\0")       true   false   false    true   false   false
str('')        float(1)      false    true    true   false   false   false
float(1)       str('+')       true   false   false    true   false   false
float(1)       str('-')       true   false   false    true   false   false
float(1)       str('0')       true   false   false    true   false   false
float(1)     str('false')     true   false   false    true   false   false
str('text')      float(1)      false    true    true   false   false   false
str('true')      float(1)      false    true    true   false   false   false
float(INF)      int(-1)        true   false   false    true   false   false
float(INF)       int(0)        true   false   false    true   false   false
float(INF)       int(1)        true   false   false    true   false   false
float(INF)     str("\0")       true   false   false    true   false   false
float(INF)      str('')        true   false   false    true   false   false
float(INF)      str('+')       true   false   false    true   false   false
float(INF)      str('-')       true   false   false    true   false   false
float(INF)      str('0')       true   false   false    true   false   false
float(INF)     str('01')       true   false   false    true   false   false
float(INF)      str('1')       true   false   false    true   false   false
float(INF)    str('false')     true   false   false    true   false   false
float(INF)    str('text')      true   false   false    true   false   false
float(INF)    str('true')      true   false   false    true   false   false
int(0)        int(-1)        true   false   false    true   false   false
int(1)        int(-1)        true   false   false    true   false   false
str("\0")       int(-1)        true   false   false    true   false   false
str('')        int(-1)        true   false   false    true   false   false
str('+')       int(-1)        true   false   false    true   false   false
str('-')       int(-1)        true   false   false    true   false   false
str('0')       int(-1)        true   false   false    true   false   false
int(-1)       str('01')      false    true    true   false   false   false
str('1')       int(-1)        true   false   false    true   false   false
str('false')     int(-1)        true   false   false    true   false   false
str('text')      int(-1)        true   false   false    true   false   false
str('true')      int(-1)        true   false   false    true   false   false
int(1)         int(0)        true   false   false    true   false   false
int(0)       str('01')      false    true    true   false   false   false
str('1')        int(0)        true   false   false    true   false   false
int(1)       str("\0")       true   false   false    true   false   false
str('')         int(1)       false    true    true   false   false   false
int(1)        str('+')       true   false   false    true   false   false
int(1)        str('-')       true   false   false    true   false   false
int(1)        str('0')       true   false   false    true   false   false
int(1)      str('false')     true   false   false    true   false   false
 str('text')       int(1)       false    true    true   false   false   false
str('true')       int(1)       false    true    true   false   false   false
str('')       str("\0")      false    true    true   false   false   false
str('+')      str("\0")       true   false   false    true   false   false
str('-')      str("\0")       true   false   false    true   false   false
str("\0")       str('0')      false    true    true   false   false   false
str("\0")      str('01')      false    true    true   false   false   false
str('1')      str("\0")       true   false   false    true   false   false
str('false')    str("\0")       true   false   false    true   false   false
str('text')     str("\0")       true   false   false    true   false   false
str('true')     str("\0")       true   false   false    true   false   false
str('')        str('+')      false    true    true   false   false   false
str('')        str('-')      false    true    true   false   false   false
str('')        str('0')      false    true    true   false   false   false
str('')       str('01')      false    true    true   false   false   false
str('')        str('1')      false    true    true   false   false   false
str('')      str('false')    false    true    true   false   false   false
str('')      str('text')     false    true    true   false   false   false
str('')      str('true')     false    true    true   false   false   false
   str('-')       str('+')       true   false   false    true   false   false
str('+')       str('0')      false    true    true   false   false   false
str('+')      str('01')      false    true    true   false   false   false
str('1')       str('+')       true   false   false    true   false   false
str('false')     str('+')       true   false   false    true   false   false
str('text')      str('+')       true   false   false    true   false   false
str('true')      str('+')       true   false   false    true   false   false
str('-')       str('0')      false    true    true   false   false   false
str('-')      str('01')      false    true    true   false   false   false
str('1')       str('-')       true   false   false    true   false   false
str('false')     str('-')       true   false   false    true   false   false
str('text')      str('-')       true   false   false    true   false   false
str('true')      str('-')       true   false   false    true   false   false
str('0')      str('01')      false    true    true   false   false   false
str('1')       str('0')       true   false   false    true   false   false
str('false')     str('0')       true   false   false    true   false   false
str('text')      str('0')       true   false   false    true   false   false
str('true')      str('0')       true   false   false    true   false   false
str('false')    str('01')       true   false   false    true   false   false
str('text')     str('01')       true   false   false    true   false   false
str('true')     str('01')       true   false   false    true   false   false
str('1')     str('false')    false    true    true   false   false   false
str('text')      str('1')       true   false   false    true   false   false
str('true')      str('1')       true   false   false    true   false   false
 str('text')    str('false')     true   false   false    true   false   false
str('true')    str('false')     true   false   false    true   false   false
 str('true')    str('text')      true   false   false    true   false   false

$a > $b > $c难题当: $a不大于 $c

A<C   : float(NAN)  >  str('a')   >   str('')
A<C   : float(NAN)  >  str('a')   >   str('1')
A<C   : float(NAN)  >  str('a')   >   str('A')
A<C   : float(NAN)  >  str('a')   >   str('0')
A<C   : float(NAN)  >  str('1')   >   str('')
A<C   : float(NAN)  >  str('1')   >   str('0')
A<C   : float(NAN)  >  str('A')   >   str('')
A<C   : float(NAN)  >  str('A')   >   str('1')
A<C   : float(NAN)  >  str('A')   >   str('0')
A<C   : float(NAN)  >  str('0')   >   str('')
A<C   :   str('')   > float(NAN)  >   str('a')
A<C   :   str('')   > float(NAN)  >   str('1')
A<C   :   str('')   > float(NAN)  >   str('A')
A<C   :   str('')   > float(NAN)  >   str('0')
A<C   :  str('a')   >   str('')   >  float(NAN)
A<C   :  str('a')   >  str('1')   >  float(NAN)
A<C   :  str('a')   >  str('A')   >  float(NAN)
A<C   :  str('a')   >  str('0')   >  float(NAN)
A<C   :  str('0')   >   str('')   >  float(NAN)
A==C  : bool(true)  >   str('')   >  float(NAN)
A==C  : bool(true)  >   str('')   > float(-INF)
A==C  : bool(true)  >   str('')   >   int(-1)
A==C  : bool(true)  >   str('')   >  float(-1)
A==C  : bool(true)  >   array()   >  float(NAN)
A==C  : bool(true)  >   array()   >  float(INF)
A==C  : bool(true)  >   array()   > float(-INF)
A==C  : bool(true)  >   array()   >   str('a')
A==C  : bool(true)  >   array()   >    int(1)
A==C  : bool(true)  >   array()   >   float(1)
A==C  : bool(true)  >   array()   >   str('1')
A==C  : bool(true)  >   array()   >   str('A')
A==C  : bool(true)  >   array()   >   int(-1)
A==C  : bool(true)  >   array()   >  float(-1)
A==C  : bool(true)  >   int(0)    > float(-INF)
A==C  : bool(true)  >   int(0)    >   int(-1)
A==C  : bool(true)  >   int(0)    >  float(-1)
A==C  : bool(true)  >  str('0')   >  float(NAN)
A==C  : bool(true)  >  str('0')   > float(-INF)
A==C  : bool(true)  >  str('0')   >   int(-1)
A==C  : bool(true)  >  str('0')   >  float(-1)
A==C  : bool(true)  >  float(0)   > float(-INF)
A==C  : bool(true)  >  float(0)   >   int(-1)
A==C  : bool(true)  >  float(0)   >  float(-1)
A==C  :   int(1)    >  str('a')   >   str('1')
A==C  :   int(1)    >  str('A')   >   str('1')
A==C  :  float(1)   >  str('a')   >   str('1')
A==C  :  float(1)   >  str('A')   >   str('1')
A==C  :  str('a')   >  str('1')   >    int(0)
A==C  :  str('a')   >  str('1')   >   float(0)
A==C  :   str('')   > float(-INF) >  NULL(NULL)
A==C  :   str('')   > float(-INF) > bool(false)
A==C  :   str('')   >   int(-1)   >  NULL(NULL)
A==C  :   str('')   >   int(-1)   > bool(false)
A==C  :   str('')   >  float(-1)  >  NULL(NULL)
A==C  :   str('')   >  float(-1)  > bool(false)
A==C  :   array()   > float(NAN)  >  NULL(NULL)
A==C  :   array()   > float(NAN)  > bool(false)
A==C  :   array()   > float(INF)  >  NULL(NULL)
A==C  :   array()   > float(INF)  > bool(false)
A==C  :   array()   > float(-INF) >  NULL(NULL)
A==C  :   array()   > float(-INF) > bool(false)
A==C  :   array()   >  str('a')   >  NULL(NULL)
A==C  :   array()   >  str('a')   > bool(false)
A==C  :   array()   >   int(1)    >  NULL(NULL)
A==C  :   array()   >   int(1)    > bool(false)
A==C  :   array()   >  float(1)   >  NULL(NULL)
A==C  :   array()   >  float(1)   > bool(false)
A==C  :   array()   >  str('1')   >  NULL(NULL)
A==C  :   array()   >  str('1')   > bool(false)
A==C  :   array()   >  str('A')   >  NULL(NULL)
A==C  :   array()   >  str('A')   > bool(false)
A==C  :   array()   >  str('0')   >  NULL(NULL)
A==C  :   array()   >   int(-1)   >  NULL(NULL)
A==C  :   array()   >   int(-1)   > bool(false)
A==C  :   array()   >  float(-1)  >  NULL(NULL)
A==C  :   array()   >  float(-1)  > bool(false)
A==C  :   str('')   > float(NAN)  > bool(false)
A==C  :   str('')   > float(NAN)  >  NULL(NULL)
A==C  :  str('A')   >  str('1')   >    int(0)
A==C  :  str('A')   >  str('1')   >   float(0)
A==C  :   int(0)    > float(-INF) >  NULL(NULL)
A==C  :   int(0)    > float(-INF) > bool(false)
A==C  :   int(0)    >   int(-1)   >  NULL(NULL)
A==C  :   int(0)    >   int(-1)   > bool(false)
A==C  :   int(0)    >  float(-1)  >  NULL(NULL)
A==C  :   int(0)    >  float(-1)  > bool(false)
A==C  :  str('0')   > float(NAN)  > bool(false)
A==C  :  str('0')   > float(-INF) > bool(false)
A==C  :  str('0')   >   int(-1)   > bool(false)
A==C  :  str('0')   >  float(-1)  > bool(false)
A==C  :  float(0)   > float(-INF) >  NULL(NULL)
A==C  :  float(0)   > float(-INF) > bool(false)
A==C  :  float(0)   >   int(-1)   >  NULL(NULL)
A==C  :  float(0)   >   int(-1)   > bool(false)
A==C  :  float(0)   >  float(-1)  >  NULL(NULL)
A==C  :  float(0)   >  float(-1)  > bool(false)
A===C :  str('0')   > float(NAN)  >   str('0')
A===C :   str('')   > float(NAN)  >   str('')
A===C :  str('a')   > float(NAN)  >   str('a')
A===C :  str('1')   > float(NAN)  >   str('1')
A===C :  str('A')   > float(NAN)  >   str('A')

有趣的字符串比较: ‘ Queen’>‘ King’>‘ Jack’>‘ Ace’

Also check out PHP 类型比较表 covering pairs:

  • isset()is_null()
  • if()empty()
  • boolean == vs. ===

检查.http://3v4l.org/MAfDu上 PHP 版本之间的差异。

在你更正了你问题的第二部分之后,我把这部分的答案留给其他人。我只是想对你的问题的第一部分给出一个最令人惊讶的答案,也就是,是否有 <>操作符是不及物的例子。就是这个。

这些都是 true:

"10" < "1a"
"1a" < "2"
"10" > "2"

如果 <是传递性的($a < $b & ; 和; $b < $c & rArr; $a < $c) ,那么最后一行将是

"10" < "2"

但是 PHP 尽可能地善良(? !)并将字符串解释为数字。

结果表明,由于上述不传递性,sort()可以根据 一样元素的输入顺序 即使没有两个元素是 ==(没有元素是 NAN)将它们排序为 与众不同顺序。我在 注释排序()中指出了这一点,其实质是:

sort(array("10", "1a", "2" )) => array("10", "1a", "2" )
sort(array("10", "2",  "1a")) => array("1a", "2",  "10")
sort(array("1a", "10", "2" )) => array("2",  "10", "1a")
sort(array("1a", "2",  "10")) => array("1a", "2",  "10")
sort(array("2",  "10", "1a")) => array("2",  "10", "1a")
sort(array("2",  "1a", "10")) => array("10", "1a", "2" )