Intereting Posts
Зачем мне нужно `str_pad ('', 4096)`, чтобы сделать промывку PHP? Автоматическая отправка электронной почты по времени и адресу электронной почты в базе данных CakePHP и пространства имен? Проблема с загрузкой php iphone / IOS6: лучший способ сохранить повернутое изображение Отправка правильного размера файла с помощью скрипта загрузки PHP Php code formatter / beautifier и php beautification вообще будет ли эта процедура вычислять число строк? как я называю эту процедуру с php? Маршрут на Laravel продолжает перенаправлять (301) на корень веб-сайта Как получить XML-данные, созданные веб-сайтом (webservice) в PHP? Как я могу исключить определенные поля формы при отправке формы без отключения поля Как получить массив PHP $ _GET? PHP удаляет новую строку Миниатюра FFMPEG в приложении php не вращается должным образом Когда использовались функции закрытия, реализованные в PHP? Не работает php strtotime

Тип-жонглирование и (строгое) большее / меньшее, чем сравнение в PHP

PHP известен своим жужжанием типа. Я должен признать, что это меня озадачивает, и мне сложно найти основные логические / фундаментальные вещи в сравнении.

Например: если $a > $b истинно, а $b > $c – true, значит, оно означает, что $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 всегда является false , не является специфичным для PHP. Это предусмотрено стандартом IEEE 754 для арифметики с плавающей точкой ( подробнее ).

  • Оператор 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) 

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

  • PHP <= оператор не рефлексивен , т. Е. $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"); // bool(false) 
  • PHP <= оператор не является транзитивным , т. Е. Из $a <= $b и $b <= $c не следует $a <= $c (пример такой же, как для == ).

  • Дополнительно: PHP <= оператор не является тотальным , то есть оба значения $a <= $b и $b <= $a могут быть ложными:

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

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

  • Оператор PHP < оператор является непереходным , т. Е. $a < $a A $a < $a никогда не является истинным. Обратите внимание, что это верно только с PHP 5.4 . Ранее INF < INF оценивался как true .

  • Оператор PHP не является асимметричным , т. Е. Из $a < $b не следует !($b < $a) (Пример такой же, как для <= несимметричный).

  • Оператор PHP < operator не является транзитивным , т. Е. Из $a < $b и $b < $c не следует $a < $c :

     var_dump(-INF < 0); // bool(true) var_dump(0 < TRUE); // bool(true) var_dump(-INF < TRUE); // bool(false) 
  • Дополнительно: PHP < operator не является трихотомным , то есть все $a < $b , $b < $a и $a == $b могут быть ложными (пример такой же, как для <= не является полным).

  • Дополнительно: 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 на PHP Sadness 52 – Операторы сравнения .

Как последнее примечание, я хочу отметить, что есть два равенства, которые PHP действительно гарантирует (в отличие от всего остального). Эти два всегда сохраняются, просто потому, что компилятор сводит один к другому:

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

В PHP нет строгих идентичных операторов сравнения ( >== или <== ) в PHP (по крайней мере , по PHP 5.6.14) , но есть несколько способов обеспечить строгую проверку типа перед проверкой Greater / Lower:

  1. Проверьте оба типа переменных: if (gettype($a) === gettype($b))
  2. Принудительно применяйте тип, например. if ((string)$a === (string)$b)
  3. Принудительный тип жонглирования, например. if (($a . '') === ($b . ''))

Обратите внимание:

  • Точность с плавающей запятой ограничена
  • INF и NAN имеют тип float под ieee754
  • Некоторая бесконечность равна некоторой другой бесконечности (начиная с PHP 5.4)
  • Научная нотация e всегда имеет тип float и никогда не является integer даже если число мало
  • Целые числа, переходящие через PHP_INT_MAX автоматически преобразуются в float
  • Поплавки через границы системы получают значение INF
  • Неопределенные переменные имеют тип и значение NULL
  • Целые числа, которым предшествует 0 , преобразуются из восьмеричного в десятичное (по соглашению)
  • Преобразование строк, содержащих целое число с ведущим числом от 0 до целого, переводит начало 0

Список некоторых экзотических сравнений:

 Очень странно:
      $ VS.  $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
   float (NAN) float (-INF) false false false false false false false
   float (NAN) float (0) false false false false false false false
   float (NAN) float (1) false false false false false false false
   float (NAN) float (INF) false 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

Равный, но не идентичный:

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

Нижний и Большой одновременно?

      $ 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 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 false
   float (NAN) str ('1') true true true true false false false
   float (NAN) str ('false') true true true true false false false
   float (NAN) str ('text') true true true true false false false
   float (NAN) str ('true') true true true true false false

Равно и тождественно:

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

Нижний или Большой:

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

$a > $b > $c Загадка, когда: $a не больше $c .

 A & lt;: float (NAN)> str ('a')> str ('')
 A & lt;: float (NAN)> str ('a')> str ('1')
 A & lt;: float (NAN)> str ('a')> str ('A')
 A & lt;: float (NAN)> str ('a')> str ('0')
 A & lt;: float (NAN)> str ('1')> str ('')
 A & lt;: float (NAN)> str ('1')> str ('0')
 A & lt;: float (NAN)> str ('A')> str ('')
 A & lt;: float (NAN)> str ('A')> str ('1')
 A & lt;: float (NAN)> str ('A')> str ('0')
 A & lt;: float (NAN)> str ('0')> str ('')
 A & lt: str ('')> float (NAN)> str ('a')
 A & lt: str ('')> float (NAN)> str ('1')
 A & lt: str ('')> float (NAN)> str ('A')
 A & lt: str ('')> float (NAN)> str ('0')
 A & lt: str ('a')> str ('')> float (NAN)
 A & lt: str ('a')> str ('1')> float (NAN)
 A & lt: str ('a')> str ('A')> float (NAN)
 A & lt: str ('a')> str ('0')> float (NAN)
 A & lt: 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')

Fun string сравнения: 'Queen' > 'King' > 'Jack' > 'Ace'

Также проверьте таблицы сравнения типов PHP, охватывающие пары:

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

Проверьте различия между версиями PHP в прямом эфире. http://3v4l.org/MAfDu .

После исправления второй части вашего вопроса я оставляю ответ на эту часть другим. Я просто хочу дать самый удивительный ответ на первую часть вашего вопроса, т. Е. Есть ли пример операторов < и > которые непереходны. Вот.

Все это true :

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

Если < были транзитивными ( $a < $b$b < $c$a < $c ), последняя строка была бы

 "10" < "2" 

но PHP пытается быть добрым (?!) и интерпретировать строки как числа, когда это возможно.

Оказывается, что из-за вышеперечисленной интранзитивности sort() может сортировать одни и те же элементы в другом порядке в зависимости от их порядка ввода, даже если ни один из двух элементов не равен == (и ни один элемент не является NAN). Я указал это в комментарии к sort () , суть которого такова:

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