Несколько сравнений с использованием типов PHP, таких как пустая строка и пустой массив, возвращают неожиданные результаты

1

Тройной равный, я думаю, все понимают; мои сомнения касаются двойного равенства. Пожалуйста, прочитайте приведенный ниже код.

<?php
//function to improve readability
function compare($a,$b,$rep)
{
    if($a == $b)
        echo "$rep is true<br>";
    else
        echo "$rep is false<br>";
}

echo "this makes sense to me<br>";
compare(NULL,0,'NULL==0');
compare(NULL,"",'NULL==""');
compare(NULL,[],'NULL==[]');
compare(0,"",'0==""');

echo "now this is what I don't understand<br>";
compare("",[],'""==[]');
compare(0,[],'0==[]');
compare(0,"foo",'0=="foo"');

echo "if I cast to boolean then it makes sense again<br>";
compare("",(bool)[],'""==(bool)[]');
compare(0,(bool)[],'0==(bool)[]');
?>

Вывод:

это имеет смысл для меня

NULL==0 is true
NULL=="" is true
NULL==[] is true
0=="" is true

теперь это то, что я не понимаю

""==[] is false
0==[] is false
0=="foo" is true

если я брошу в boolean, тогда это имеет смысл снова

""==(bool)[] is true
0==(bool)[] is true

Я ожидал бы, что пустой массив будет "равен" пустой строке или целому числу 0. И я не ожидал бы, что целое число 0 будет "равно" строке "foo". Честно говоря, я не совсем понимаю, что делает PHP за кулисами. Может кто-нибудь, пожалуйста, объясните мне, что здесь происходит?

  • 2
    Не пытайтесь понять PHP, просто примите участие в изучении / обращении к произвольным таблицам правил: php.net/manual/en/types.comparisons.php .
  • 0
    дубликат: stackoverflow.com/questions/80646/…
Показать ещё 21 комментарий
Теги:
boolean

2 ответа

1

Простой ответ заключается в том, что именно так php был разработан для работы.

Результаты хорошо определены в операциях сравнения документов и сравнительных таблицах.

A == сравнение между массивом (ваши первые два запроса) и строкой всегда приводит к false.

В сопоставлении == между числом и строкой (ваш третий запрос) строка преобразуется в число, а затем производится цифровое сравнение. В случае 0 == 'foo' строка 'foo' численно оценивается до 0 и тест становится 0 == 0 и возвращает true. Если строка была "числовой", например "3", результат в вашем случае был бы ложным (0 не равно 3).

Является ли дизайн "правильным" (что бы это ни значило), является спорным. Это, конечно, не всегда очевидно. Иллюстративный пример потенциальной ярости дебатов можно найти в Bug # 54547, где разработчики утверждают, что дизайн основан на истории php как на веб-языке, где все является строкой и должно быть оставлено в покое, а другие утверждают, что php " нарушает принцип наименьшего удивления ".

Во избежание использования неопределенности === везде, где это возможно, с дополнительным преимуществом потенциального выявления допущений в вашем коде, которые могут быть недействительными.

  • 0
    Читая этот отчет об ошибке, мне кажется, что есть шанс, что изменения могли быть внесены, но из-за агрессивной толпы, готовой злоупотребить основными разработчиками, было решено закрыть. Если ничего другого, это демонстрирует, как не поддерживать сообщение об ошибке ;-) .
0

Как уже говорилось, правила автоматического каста PHP могут быть довольно сложными, и стоит использовать === если вы не знаете, что обе стороны будут одного типа. Однако я считаю, что могу объяснить это:

""==[] (returns false)

Исходная строка "" указывает, что сравнение будет строковым, и, таким образом, [] передается в строку. Когда это произойдет, правая часть сравнения будет установлена на слово Array. Поэтому вы делаете это сравнение:

"" == "Array" (returns false)

и, следовательно, false результат.

Изменение: полезный комментарий ниже вызывает сомнение в моем ответе с помощью этого примера с живым кодом. Мне должно быть интересно узнать, какие другие ответы предоставляются.

  • 0
    Я считаю, что это обоснование неверно: ideone.com/povYMk
  • 0
    Да, я тоже это попробовал. И на самом деле это как раз мой вопрос. Если я не могу понять, как работает ==, я не могу использовать его на 100% спокойно. Конечно, я всегда мог использовать ===, но иногда == действительно удобно. Если бы я мог предсказать результат, не глядя на таблицу, конечно ...
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню