PHP
April 2013 9

Особенности логического сравнения в PHP

From Sandbox
Четвертого апреля на stackoverflow появился вопрос, касающийся работы операторов сравнения в PHP. Почти сразу же на него поступил развернутый ответ. Наверняка для многих это является интересной темой.

Вопрос


PHP славится своим приведением типов. Я потратил много времени в поисках основ логики сравнения в нем.

Например: если $a > $b является истиной и $b > $c является истиной, значит ли это, что $a > $c также является истиной?

Руководствуясь простейшей логикой я могу предположить что это выражение также верно, однако я не очень доверяю PHP в этом в вопросе. Может кто-нибудь привести мне пример, в котором данное утверждение будет ложным?

Также мне интересна работа операторов «больше» и «меньше». Изменится ли результат сравнения при переворачивании выражения:
# precondition:
if ($a === $b) {
    throw new Exception(
       'both are strictly equal, can not compare strictly for greater or smaller'
    );
}

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

Для большинства комбинаций типов работа операторов сравнения больше/меньше не документирована.

Ответ


Оператор сравнения в PHP в некоторых моментах отличается от канонического определения:

Отношение равенства должно быть рефлексивным, симметричным и транзитивным:

  • Оператор == в PHP не рефлексивен, т. е. $a == $a не всегда является истиной:
    var_dump(NAN == NAN); // bool(false)
    Примечание: То, что сравнение с участием NAN всегда является ложным не является особенностью PHP. Это поведение определено в стандарте IEEE 754 формата представления чисел с плавающей точкой (пояснения на stackoverflow);

  • Оператор == симметричен, т. е. $a == $b и $b == $a всегда равны;

  • Оператор == не транзитивен, т. е. $a == $b и $b == $c не означает, что $a == $c:
    var_dump(true == "a"); // bool(true)
    var_dump("a" == 0);    // bool(true)
    var_dump(true == 0);   // bool(false)
    

Отношение <=/>= должно быть не рефлексивным, антисимметричным и транзитивным:

  • Оператор <= в PHP не рефлексивен, т. е. выражение $a <= $a не всегда является истинным (см. пример для ==);

  • Оператор <= не антисимметричен, т. е. истинность выражений $a <= $b и $b <= $a не означает, что $a == $b:
    var_dump(NAN <= "foo"); // bool(true)
    var_dump("foo" <= NAN); // bool(true)
    var_dump(NAN == "foo"); // bool(false)

  • Оператор <= не транзитивен, т. е. истинность выражений $a <= $b и $b <= $c не означает, что $a <= $c (пример такой же, как и для оператора ==).

  • Оператор <= не является полным, т. е. и $a <= $b, и $b <= $a могут быть ложными:
    var_dump(new stdClass <= new DateTime); // bool(false)
    var_dump(new DateTime <= new stdClass); // bool(false)

Отношение строгого неравенства </> должно быть антирефлексивным, асимметричным и транзитивным:

  • Оператор < в PHP антирефлексивен, т. е. $a < $a всегда является ложным. Это актуально начиная с версии PHP 5.4. В предыдущих версиях INF < INF является истинным;

  • Оператор < не асимметричен, т. е. истинность выражения $a < $b не означает, что !($b < $a) является истинным (см. пример для <=);

  • Оператор < не транзитивен, т. е. из истинности $a < $b и $b < $c не следует, что $a < $c также является истиной:
    var_dump(-INF < 0);    // bool(true)
    var_dump(0 < TRUE);    // bool(true)
    var_dump(-INF < TRUE); // bool(false)

  • Дополнительно: Оператор < не трихотомичен, т. е. выражения $a < $b, $b < $a и $a == $b могут быть ложными (пример такой же, как и для <=);

  • Дополнительно: Оператор < может быть закольцованным, т. е. бывают случаи, когда $a < $b, $b < $c и $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 converted to double» уровня notice.

Вы можете найти несколько восхитительных графиков в статье PHP Sadness 52 — Операторы сравнения.

И в конце я хочу отметить, что два равенства в PHP гарантированы (в отличии от почти всего остального) потому что интерпретатор приводит их к одному виду:
($a > $b) == ($b < $a)
($a >= $b) == ($b <= $a)

UPD: Второй ответ


В PHP (актуально для версии 5.5.0beta2) нет строгого сравнения >== или <== с проверкой типов, но есть несколько способов сравнить типы до сравнения больше/меньше:
  1. Сравнить типы переменных if ( gettype($a)===gettype($b) ) ...
  2. Явно привести переменные к нужному типу if ( (string)$a===(string)$b ) ...
  3. Использовать манипуляцию с типами if ( ($a.'')===($b.'') ) ...

Также обратите внимание на следующее:
  • Числа с плавающей точкой имеют ограниченную точность;
  • Константы NAN и INF являются типом float;
  • Сравнение INF с INF является математически неверным;
  • Числа в e-нотации являются типом float, даже если они небольшие;
  • Целые числа превышающие PHP_INT_MAX автоматически преобразуются в числа с плавающей точкой;
  • Числа с плавающей точкой выходящие за границы определенные системой содержат INF;
  • Необъявленные переменные возвращают NULL;
  • При присвоении целые числа начинающиеся с 0 преобразуются из восьмеричного в десятеричный вид;
  • При приведении строки к целому числу оно теряет начальные нули.

Несколько специфических сравнений
Необычно
     $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  
Примечание переводчика: В ответе выше сказано, что любое сравнение с NAN возвращает 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)  >  NULL(NULL) 
A===C :   str('')   > float(NAN)  >   str('')   
A<C   :   str('')   > float(NAN)  >   str('a')  
A<C   :   str('')   > float(NAN)  >   str('1')  
A==C  :   str('')   > float(NAN)  > bool(false) 
A<C   :   str('')   > float(NAN)  >   str('A')  
A<C   :   str('')   > float(NAN)  >   str('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('a')   > float(NAN)  >   str('a')  
A<C   :  str('a')   >   str('')   >  float(NAN) 
A<C   :  str('a')   >  str('1')   >  float(NAN) 
A==C  :  str('a')   >  str('1')   >    int(0)   
A==C  :  str('a')   >  str('1')   >   float(0)  
A<C   :  str('a')   >  str('A')   >  float(NAN) 
A<C   :  str('a')   >  str('0')   >  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('1')   > float(NAN)  >   str('a')  
A===C :  str('1')   > float(NAN)  >   str('1')  
A<C   :  str('1')   > float(NAN)  >   str('A')  
A<C   :  str('1')   >   str('')   >  float(NAN) 
A<C   :  str('1')   >  str('0')   >  float(NAN) 
A<C   :  str('A')   > float(NAN)  >   str('a')  
A===C :  str('A')   > float(NAN)  >   str('A')  
A<C   :  str('A')   >   str('')   >  float(NAN) 
A<C   :  str('A')   >  str('1')   >  float(NAN) 
A==C  :  str('A')   >  str('1')   >    int(0)   
A==C  :  str('A')   >  str('1')   >   float(0)  
A<C   :  str('A')   >  str('0')   >  float(NAN) 
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)  >   str('a')  
A<C   :  str('0')   > float(NAN)  >   str('1')  
A==C  :  str('0')   > float(NAN)  > bool(false) 
A<C   :  str('0')   > float(NAN)  >   str('A')  
A===C :  str('0')   > float(NAN)  >   str('0')  
A==C  :  str('0')   > float(-INF) > bool(false) 
A<C   :  str('0')   >   str('')   >  float(NAN) 
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) 

Забавное сравнение строк: 'Queen' > 'King' > 'Jack' > 'Ace'

Также посмотрите таблицу сравнения типов в PHP в которой указаны сравнения:
  • isset() и is_null()
  • if() и empty()
  • Различия в == и ===

Код, который сгенерировал списки на Git Hub
Различия в версиях PHP: http://3v4l.org/MAfDu
+32
9.5k 197
Comments 17
Top of the day