Жонглювання типу та (суворі) більше / менше порівнянь у PHP


115

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)

Для більшості всіх комбінацій типів порівняння ці більші / менші оператори порівняння не задокументовані, тому читання посібника не дуже допомогло в цьому випадку.


Я думаю, ви хочете виправити цей рядок ($a > $b) !== ($b < $a)?
Вальтер Трос

ах, добре, так що я це неправильно зрозумів. Доведеться відповідно виправити свою відповідь. Смішно всім, хто пише трактати замість відповідей і не читають уважно ваше запитання ...
Walter Tross

Відповіді:


208

Оператори порівняння PHP відхиляються від комп'ютерних наукових визначень кількома способами:

Для того, щоб скласти відношення еквівалентності == , повинно бути рефлексивним, симетричним та перехідним:

  • ==Оператор PHP не є рефлексивним , тобто $a == $aне завжди відповідає дійсності:

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

    Примітка. Те, що будь-яке порівняння, NANяке завжди falseстосується, не є специфічним для PHP. Це передбачено стандартом IEEE 754 для арифметики з плаваючою комою ( детальніше ).

  • РНР ==оператор симетричний , тобто $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не завжди відповідає дійсності (Приклад такий же, як і для ==).

  • <=Оператор 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ніколи не відповідає дійсності. Зауважте, що це стосується лише PHP 5.4 . Раніше INF < INFоцінювали до true.

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

  • <Оператор PHP не є транзитивним , тобто з $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 не є трихотомом , тобто всім $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)

2
Нічого собі, приємна відповідь. Тож неможливо сформулювати логічні вирази з PHP, як ($a > $b) and ($b > $c)у випадку, $a > $cхоча документація каже, що ті </ >оператори кажуть, що вони суворі ?
хакре

26
Оператори ІМХО дотримуються математичних правил, але лише при роботі з одними і тими ж даними. Кастинг типів - це те, що справді створює плутанину тут (і у багатьох інших ситуаціях). При порівнянні чисел і рядків та спеціальних значень перетворення типів робляться перед операторами, тому строго кажучи, оператори порівняння не плутають, лиття - ...
ivanhoe

6
@ ivanhoe011 Правда така: Обидва :) Правила порівняння PHP та правила кастингу PHP відрізняються , ви не можете просто сказати, що $a == $bце те саме, що (type) $a === (type) $b. Простий приклад цього - це "15" == "0xf", але (int) "15" !== (int) "0xf". І правила порівняння, і кастинг в PHP абсолютно божевільні ^^
NikiC

3
@NikiC: (int)"0xf"оцінює до цілого числа 0, так, звичайно 0 !== 15. Порівняння в цьому прикладі поводиться точно так, як очікувалося. Це кастинг, який тут заплутаний. Я визнаю, це (INF < INF) === trueбула справжня проблема порівняння, але це був особливий випадок, і це було вирішено, як ви вказали. Чудова відповідь .. +1
FtDRbwLXw6

1
Я не обов'язково звинувачую дизайнерів PHP у деяких рішеннях, які мали сенс щодо примусу типу… Але я відчуваю, що, мабуть, помітили результати цих дизайнерських виборів і негайно усвідомивши вибір, очевидно, помилялися. Найбільш очевидний приклад - коментар @ ravz.
Чад

88

У PHP немає чітких ідентичних операторів порівняння ( >==або <==) (принаймні по PHP 5.6.14) , але є кілька способів застосувати сувору перевірку типу перед перевіркою Великого / Нижнього:

  1. Перевірте обидва типи змінних за допомогою if (gettype($a) === gettype($b))
  2. Формуйте потрібний для вас тип ролі, наприклад. if ((string)$a === (string)$b)
  3. Примушуйте потрібний тип жонглювання, наприклад. if (($a . '') === ($b . ''))

Зверніть увагу, що:

  • Точність з плаваючою точкою обмежена
  • INFі NANмають тип floatпід
  • Деякі нескінченності дорівнюють іншій нескінченності (починаючи з 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 false
  float (NAN) int (-1) false false false false false false
  float (NAN) int (0) false false false false false false false
  float (NAN) int (1) false false false false false false false

Рівні, але не тотожні:

     $ за VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  NULL (NULL) масив () 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 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 false false
 bool (false) float (0) false false true true true true false
 bool (false) int (0) false false true true true true false
   str ('') bool (false) false false true true true true false
 bool (false) str ('0') false false правда true true true false
 float (-INF) bool (true) false false true true true true false
  bool (true) float (1) false false true true true false 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 false
  bool (true) int (1) false false true true true false false
  bool (true) str ("\ 0") false false true true true true false
  bool (true) str ('+') false false true true true true false
  bool (true) str ('-') false false правда true true true false
  bool (true) str ('01 ') false false справжній true true false
  bool (true) str ('1') false false правда true true true false
  bool (true) str ('false') false false true true true false false
 str ('текст') bool (правда) false false true true true true false
 str ('true') bool (true) false false true true true false false
    int (0) float (0) false false true true true true false
  str ("\ 0") float (0) false false true true true true false
   str ('') float (0) false false true true true true false
   str ('+') float (0) false false true true true true false
   str ('-') float (0) false false true true true true false
   str ('0') float (0) false false true true true true false
 str ('false') float (0) false false true true true true false
 str ('текст') 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 false 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 true false
   str ('') int (0) false false true true true true false
   str ('+') int (0) false false true true true true false
   str ('-') int (0) false false true true true true false
    int (0) str ('0') false false true true true true false
 str ('false') int (0) false false true true true true false
 str ('text') int (0) false false true true true true false
 str ('true') int (0) false false true true true true false
    int (1) str ('01 ') false false справжній true true false
    int (1) str ('1') false false true true true true false
   str ('1') str ('01 ') false false правда 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 false
  float (NAN) str ('') true true true true true false false false
  float (NAN) str ('+') true true true true true false false
  float (NAN) str ('-') true true істинно true true false false
  float (NAN) str ('0') true true true true true false false false
  float (NAN) str ('01 ') true true true true true false false
  float (NAN) str ('1') true true true true true false false false
  float (NAN) str ('false') true true true true true false false
  float (NAN) str ('text') true true true true true false false
  float (NAN) str ('true') 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
 float (-INF) float (-INF) false false правда true true true true
  float (INF) float (INF) false false справжній true true true

Нижній або великий:

     $ за VS. $ b $ a> $ b $ a <$ b $ a <= $ b $ a> = $ b $ a == $ b $ a === $ b
  NULL (NULL) bool (true) false true true true false false false false
 float (-INF) NULL (NULL) true false false false true false false
  NULL (NULL) float (1) false true true true false false false false
  float (INF) NULL (NULL) true false false false true false false
  float (NAN) NULL (NULL) true false false false true false false
  NULL (NULL) int (-1) false true true true false false false
  NULL (NULL) int (1) false true true true false false false
  NULL (NULL) str ("\ 0") false true true false false false false
  NULL (NULL) str ('+') false true true true false false false false
  NULL (NULL) str ('-') false true true true false false false false
  NULL (NULL) str ('0') false істина true false false false false
  NULL (NULL) str ('01 ') false true true true false false false false
  NULL (NULL) str ('1') false істина true false false false false
  NULL (NULL) str ('false') false true true false false false false
  NULL (NULL) str ('текст') false true true true false false false false
  NULL (NULL) str ('true') false true true false false false false
   array () bool (true) false true true true false false false
 float (-INF) array () false true true true false 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 true false false false false
  float (NAN) array () false true true true false 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 true false false false
   array () str ('+') true false false true false false
   array () str ('-') true false false true true false false
   array () str ('0') true false false true 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 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 true false false
   float (1) bool (false) true false false true false false
  float (INF) bool (false) true false false false true false false
  float (NAN) bool (false) true false false true true false false
 bool (false) int (-1) false true true false false false false
    int (1) bool (false) true false false true false false
 bool (false) str ("\ 0") false true true true false false false
 bool (false) str ('+') false true true true false false false
 bool (false) str ('-') false true true true false false false
 bool (false) str ('01 ') false true true true false false false
   str ('1') bool (false) true false false true true false false
 bool (false) str ('false') false true true true false false false
 str ('text') bool (false) true false false true true false false
 str ('true') bool (false) true false false true 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 false
  bool (true) str ('0') true false false справжнє false false
 float (-INF) float (0) false true true true false false false false
 float (-INF) float (1) false true true true false false false
  float (INF) float (-INF) true false false false true false false
 float (-INF) int (-1) false true true true false false false
 float (-INF) int (0) false true true true false false false false
 float (-INF) int (1) false true true true false false false
 float (-INF) str ("\ 0") false true true true false false false false
 float (-INF) str ('') false true true true false false false false
 float (-INF) str ('+') false true true true false false false false
 float (-INF) str ('-') false true true true false false false false
 float (-INF) str ('0') false true true true false false false false
 float (-INF) str ('01 ') false true true true false false false false
 float (-INF) str ('1') false true true true false false false false
 float (-INF) str ('false') false true true true false false false
 float (-INF) str ('text') false true 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
  float (INF) float (0) true false false true false 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 true false false false false
   str ('1') float (0) true false false true true false false
  float (INF) float (1) true false false true 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 true false false
   str ('') float (1) false true true true false false false
   float (1) str ('+') true false false true true false false
   float (1) str ('-') true false false true true false false
   float (1) str ('0') true false false true true false false
   float (1) str ('false') true false false true false false
 str ('текст') float (1) false true true true false false false
 str ('true') float (1) false true true false false false false
  float (INF) int (-1) true false false true false false
  float (INF) int (0) true false false true true false false
  float (INF) int (1) true false false true false false
  float (INF) str ("\ 0") true false false true true false false
  float (INF) str ('') true false false true true false false
  float (INF) str ('+') true false false true true false false
  float (INF) str ('-') true false false true true false false
  float (INF) str ('0') true false false true true false false
  float (INF) str ('01 ') true false false true true false false
  float (INF) str ('1') true false false true true false false
  float (INF) str ('false') true false false справжній false false
  float (INF) str ('text') true false false true true false false
  float (INF) str ('true') true false false справжній 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 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 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 true false false false
    int (1) str ('+') true false false true 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 true false false false
 str ('true') int (1) false true true false false false false
   str ('') str ("\ 0") false true true true false false false false
   str ('+') str ("\ 0") true false false true true false false
   str ('-') str ("\ 0") true false false true true false false
  str ("\ 0") str ('0') false true true true false false false false
  str ("\ 0") str ('01 ') false true true true false false false
   str ('1') str ("\ 0") true false false true true false false
 str ('false') str ("\ 0") true false false true false false
 str ('текст') str ("\ 0") true false false true true false false
 str ('true') str ("\ 0") true false false true false false false
   str ('') str ('+') false true true true false false false false
   str ('') str ('-') false true true true false false false
   str ('') str ('0') false справжній true true false false false false
   str ('') str ('01 ') false true true true false false false
   str ('') str ('1') false true true true false false false
   str ('') str ('false') false true true true false false false
   str ('') str ('текст') false true true true false false false
   str ('') str ('true') false true true true false false false
   str ('-') str ('+') true false false справжнє false false
   str ('+') str ('0') false істина true false false false false
   str ('+') str ('01 ') false true true true false false false
   str ('1') str ('+') true false false true true false false
 str ('false') str ('+') true false false true false false
 str ('текст') str ('+') true false false true true false false
 str ('true') str ('+') true false false true false false
   str ('-') str ('0') false істина true false false false false
   str ('-') str ('01 ') false true true true false false false
   str ('1') str ('-') true false false справжнє false false
 str ('false') str ('-') true false false true false false
 str ('текст') str ('-') true false false true true false false
 str ('true') str ('-') true false false справжній false false
   str ('0') str ('01 ') false true 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 ('текст') str ('0') true false false true true false false
 str ('true') str ('0') true false істинно true false false
 str ('false') str ('01 ') true false false true false false
 str ('текст') 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 true false false false
 str ('текст') str ('1') true false false true true false false
 str ('true') str ('1') true false false справжній false false
 str ('текст') 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 (вірно)> str ('')> int (-1)
A == C: bool (true)> str ('')> float (-1)
A == C: bool (true)> масив ()> float (NAN)
A == C: bool (true)> масив ()> float (INF)
A == C: bool (true)> масив ()> float (-INF)
A == C: bool (true)> масив ()> str ('a')
A == C: bool (true)> масив ()> int (1)
A == C: bool (true)> масив ()> float (1)
A == C: bool (true)> масив ()> str ('1')
A == C: bool (true)> масив ()> str ('A')
A == C: bool (true)> масив ()> int (-1)
A == C: bool (true)> масив ()> float (-1)
A == C: bool (true)> int (0)> float (-INF)
A == C: bool (вірно)> 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 (вірно)> 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 (помилково)
A == C: str ('')> float (-1)> NULL (NULL)
A == C: str ('')> float (-1)> bool (false)
A == C: масив ()> float (NAN)> NULL (NULL)
A == C: array ()> float (NAN)> bool (false)
A == C: масив ()> float (INF)> NULL (NULL)
A == C: масив ()> float (INF)> bool (false)
A == C: масив ()> float (-INF)> NULL (NULL)
A == C: array ()> float (-INF)> bool (false)
A == C: масив ()> str ('a')> NULL (NULL)
A == C: array ()> str ('a')> bool (помилково)
A == C: масив ()> int (1)> NULL (NULL)
A == C: масив ()> int (1)> bool (помилково)
A == C: масив ()> float (1)> NULL (NULL)
A == C: array ()> float (1)> bool (false)
A == C: масив ()> str ('1')> NULL (NULL)
A == C: масив ()> str ('1')> bool (помилково)
A == C: масив ()> str ('A')> NULL (NULL)
A == C: array ()> str ('A')> bool (помилково)
A == C: масив ()> str ('0')> NULL (NULL)
A == C: масив ()> int (-1)> NULL (NULL)
A == C: масив ()> int (-1)> bool (помилково)
A == C: масив ()> 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 (хибно)
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 (помилково)
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 string порівняння: 'Queen' >'King' >'Jack' >'Ace'

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

  • isset() і is_null()
  • if() і empty()
  • булева ==vs.===

Перевірте відмінності між PHP-версіями, на яких вони живуть. http://3v4l.org/MAfDu .


26
+1 не кажучи вже прокручувані "таблиці" із заголовками фіксованих стовпців - чудова ідея;)
hakre

Чи потрібно використовувати строгий оператор під час типового лиття? Я маю на увазі, що ви написали, if ( (string)$a===(string)$b )але чи не зовсім так if ( (string)$a==(string)$b )?
Войтек

@Voitcus так і для типів-актерів (string)1==(string)'01'-> bool(true)і для типу-жонглювання (1 . '')=='01'-> bool(true)не зовсім так, як ===коли б ви потрапили bool(false)на обидва рахунки
CSᵠ

1
Один вибірка ніт: восьмеричні значення не "перетворюються за призначенням", вони інтерпретуються компілятором, який повинен перетворити ASCII у фактичні двійкові числа.
IMSoP

INFINITY is equal to INFINITY which is mathematically incorrect!це рішуче дискусійне твердження. Також зауважте, що NaNза умовами він не більший, менший або рівний будь-якій мові програмування, яку я знаю.
DaveRandom

22

Після виправлення другої частини вашого запитання я залишаю відповідь на цю частину іншим. Я просто хочу дати найдивовижнішу відповідь на першу частину вашого запитання, тобто, чи є приклад того, <і >оператори нечутливі. Ось.

Це все true:

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

Якби <були транзитивні ( $a < $b$b < $c$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" )

1
попередній коментар стосується частини відповіді (пов'язаної з другою частиною запитання), яку я тим часом видалив
Вальтер Трос

Видалено це зараз;) І приємна нова sort()таблиця, її також підібрали для практичних наслідків під час написання відповідної публікації в блозі Найбільше значення PHP . Ще раз дякую за вашу відповідь.
хакре

Чи означає це, що слід користуватися, usortколи це можливо?
Войтек

2
@Voitcus: Я думаю, ти маєш на увазі usort($arr, 'strcmp'). Це працює (звичайно, для струн), але найкраще використовувати sort($arr, SORT_STRING).
Вальтер Трос

@WalterTross Я маю на увазі завжди використовувати власну функцію (не тільки для рядків), щоб переконатися, що вона завжди правильна
Voitcus
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.