PHP

индекс
206,76

Чудеса оператора ==

Как вы думаете, обладает ли оператор == в PHP свойством транзитивности? Транзитивность в данном случае означает следующее:
если $a == $b и $b == $c, то $a == $c
Первое, что приходит в голову: "это ж очевидно, конечно обладает!"
А вот и нет:
     '0' == false; // true
     false == '';  // true
     '0' == '';    // false :)))
Добро пожаловать в увлекательный мир PHP. Занавес...

P.S.: Вот тут (и ещё тут, спасибо посмотреть профиль Kupyc), по всей видимости, это дело задокументировано (в комментариях дополнительных много всего интересного).

P.P.S.: Пост не для холивара, а к сведению и чтобы улыбнуться. Сам активно пишу на PHP.

+6
17 октября 2007, 17:50
6

комментарии (120)

+1
Kupyc #
Да, это верхушка айсберга "Преобразование типов". Имхо, скорее дело закоментировано по http://ru2.php.net/manual/ru/language.ty…
0
davojan #
О, точно!
Спасибо, сейчас добавлю...
+4
wecom #
ну, в общем-то, и нет ничего удивительного.
вот оператор === как раз таки обладает таким нужным и полезным свойством :)
0
dolotov #
Как раз === и хотел привести в качестве аргумента.
Если нужны строгие определения переменных, то вам в C++.
Конечно, к каждому большому удобству идёт в комплекте и своё маленькое неудобство. О нём достаточно просто не забывать.

Кстати, оператор "==" в Perl работает примерно аналогично.
0
ulfurinn #
> perl -e "print '0' == ''"
1

Именно что "примерно" ;)
0
kvas #
Просто в перле "==" — оператор сравнения чисел. Он всё приводит к числам. А для строк там "eq". Ну и конечно '0' eq '' не будет истинным.
+1
Rommidze #
Я для себя завёл негласное правило, всегда пользоваться только операторами === и !==. Наводит ясность и хорошо защищает от дальнейших проблем.
+2
abba #
это уже паранойя
0
Rommidze #
Да. Паранойя это моя особенность, представляющая определённую ценность. Испоьзование таких операторов является не самым ярким её проявлением.
НЛО прилетело и опубликовало эту надпись здесь
+3
den_rad #
Это не очень удобно, например, когда вы сравниваете число с ячейкой из БД , которая имеет тип string
0
mayhem #
имеет смысл приводить переменные к правильному типу. и безопасность выше и код логичней
0
mocksoul #
производительность страдает. Самое умное - использовать это _когда_нужно_.
0
Rommidze #
Откуда сведения?

Эксперемент №1. Проверка оператора ===
time echo "<?php \$a='0'; \$b=1; for (\$i = 0; 10000000 > \$i; ++\$i) \$c = (\$a === \$b); ?>" | php
real 0m1.889s
user 0m1.864s
sys 0m0.012s

Эксперемент №2. Проверка оператора ==
time echo "<?php \$a='0'; \$b=1; for (\$i = 0; 10000000 > \$i; ++\$i) \$c = (\$a == \$b); ?>" | php
real 0m3.132s
user 0m3.120s
sys 0m0.008s

Очевидно, что оператор === почти в два раза быстрее чем ==. Для достоверности эксперемента, замеры произвёл несколько раз. Причина банальна: при операторе === интерпретатор не производит преобразование типов: если не совпали, то false.
0
Rommidze #
Нет. Не в два раза быстрее, а примерно в пять раз. В выше приведённых примерах существенную часть занимает холостой ход цикла и оператор присваивания:

time echo "<?php \$a='0'; \$b=1; for (\$i = 0; 10000000 > \$i; ++\$i) \$c = 0; ?>" | php
real 0m1.662s
user 0m1.652s
sys 0m0.004s
+1
gro #
Не нужно заводить правил, а нужно знать, как что работает и тогда не будет проблем.
Операторы сравнения и тождественности, это разные операторы, каждый для своего случая.
Если бы один из них был определенно лучше другого во всех случаях, то он бы один в языке и остался.
+1
GarAlex #
Это не занавес, а гибкость ;-)
Для более строгого сравнения есть ===.
+10
sys #
вообще все законно
перед сравнением пхп должен привести все к одному типу
'0' == false; // (bool)'0' вернет false
false == ''; // тут тоже самоме по сути
'0' == ''; // а тут уже сравнение строк
0
MaGIc2laNTern #
Собственно, да.

ml@pivo ~ $ echo "<? echo 0 == '' ?>" | php && echo
1
НЛО прилетело и опубликовало эту надпись здесь
0
sys #
результат будет true
но это не значит что '0' == ''
0
Kupyc #
В Вашей записи и правда нет никакой тонкости, не поймите неправильно :). Автор же демонстрирует неплохой пример php-софизма, в чем, собственно, и заключается смысл топика, если я все верно понимаю - в софизме.
+2
Siddthartha #
Просто программист не должен начинать с PHP. Он должен получить сперва классическое для этой области знаний образование. Любой писавший на Си, осторожно относится к приведению типов, даже если этим занимается движок интерпретатора. Каждый раз когда пишешь что-то вроде $string==false должен зазвонить колокольчик у виска - "верно ли я понимаю процесс сравнения здесь?"

Отсутствие транзитивности вполне можно получить и в других языках, где есть традиция определения операторов для сложных типов данных.

Так что ничего пародоксального в данном факте нет, я считаю. Оператор не обязан быть транзитивен при манипуляциях со столь далекими друг от друга типами.
+1
Uznick #
Не надо писать $string == false, надо писать if !$string.

А в том факте действительно ничего парадоксального нет, нужно просто понимать механизмы языка, с которым имеешь дело.
0
Siddthartha #
А я так никогда и не пишу. Это перефразированный пример из топика. И бывает что подобные конструкции чем-то оправданны... Нельзя лишь делать это автоматом и необдуманно.
0
mx2000 #
Как раз таки следует писать (if $string == false).
0
mx2000 #
А еще лучше if(false == $string). ы!
0
sys #
для работы со строками лучше пользоваться строковами операторами
if(strlen($string))
и самому спокойней и каждому кто будет твой код ковырять сразу бедут понятно что $string это строка
0
DeadMoroz #
а по-моему если надо убедиться, что строка непустая, достаточно сравнить ее с пустой строкой. зачем заставлять интерпретатор считать кол-во символов в строке, если оно вам не надо?
0
Devgru #
вот именно, нужно писать просто: if($string==="")
0
akral #
empty($foo)?
0
mivlad #
А чего считать, он это число и так знает :-)
0
DeadMoroz #
Ну так все равно, сперва нужно "преобразовать" строку в ее длину а потом привести целое число к булевому типу (если проверять if(strlen($string))). Вместо того чтобы просто сравнить две строки.
0
MikeOzornin #
Длина хранится в строке в одной из байтов. Не нужно ничего преобразовывать (:
Операция сравнения строк тоже тривиально, ага?
0
HeadFore #
Это не Паскаль, чтобы в foo[0] хранить размер. Здесь строки как в Си, т.е. в конце символ с кодом 0.
0
mivlad #
Наверняка ведь при сравнении строк сначала сравнивается их длина.
0
Devgru #
так делать можно только новичкам, которые могут забыть вместо одного знака равно написать два.
когда же человек уже навострился в программировании в C-подобных языках, это уже не нужно, и будет только мешать
0
mx2000 #
Так следует делать, чтобы акцентировать свои намерения. конструкция if(!foo) априори хуже читается, особенно в сложных выражениях. Сравните
if(foo && (!(a + f1(b, c)) || f2(c)))
и
if(foo == true && ((a + f1(b, c)) == false) || f2(c) == true))
0
Devgru #
это дело привычки. не могу сказать что лично мне нижняя на порядок легче
0
Uznick #
Ну-ну
0
Biollante #
Программист должен программировать. На подходящем ему языке.
А классическое образование приводит к забитой теорией голове и неспособности решать практические задачи.
У знакомых тут команда классиков пишет. По два высших у каждого. Умные алгоритмы знают, да. А вот о безопасности понятия ВООБЩЕ не имеют, SQL injection на каждом углу пролезает.
0
artofpiano #
Как бы не умеют просто писать, вот и всё. Они не классики, они просто слабые программисты, а дипломы сейчас только ленивые не получили.
0
Siddthartha #
Я уверен, что php - инструмент для грамотных программистов, обязательно знакомых со строго типизированными языками. Тогда он "играет".

В противном случае это сродни магии. "Ух-ты как себя ведет программа!" на каждом шагу возникает.
0
MTonly #
Несколько странно, что человек, «активно пишущий на PHP», удивляется, получая закономерное false при сравнении разных строк. ;-)
0
davojan #
Я удивляюсь не этому, а отсутствию наличия транзитивности, которая, казалось бы, очевидно должна присутствовать :)
–1
korchasa #
Она и присутствует ;)
Исправьте пожалуйста весь пост
0
korchasa #
Лучше раскройте тему того, что при сравнении == производится попытка привести к одинаковым типам.
+1
davojan #
Не понял вас. О чём вы? Транзитивности нет, нечего исправлять...
0
korchasa #
А откуда она там должна взяться? Кто-нибудь вам говорил, что == транзитивен?

Лучше распишите, что происходит, когда вы делаете ==, а не просто "первое, что приходит на ум". Так напишите, тем, кто не знает, почему ее тут нет.

А то пока от топика у новичков создается впчатление, что в пыхе опять что-то не так, хотя на самом деле это в знаниях "не так" ;)
0
korchasa #
Сорри, в комменте имел ввиду транзитивность операции сравнения. В смысле ===
0
davojan #
Ну кто-кто? не помню, возможно на уроках математики. Если A равно B и B равно С, то A равно С - согласитесь, логично.

А зачем расписывать то, что в прекрасной документации php и так написано чёрным по белому? Ссылки я дал.

А что новичков обманывать, в пыхпыхе действительно много что "не так", однако мне это не мешает его по своему "любить" и писать на нём много лет.

Мои знания тут не причём. Почему транзитивности нет в данном случае - совершенно понятно - и я уверен, что большинство программистов знает принципы сравнения, однако я так же уверен, что почти никто не обращал внимания на отсутствие транзитивности.
0
MikeOzornin #
== - это не "равно". Это что-то типа "А, при приведении типов, даст результат сходный с Б".
0
blockdog #
Так все же просто...

'0' — это строка
'' — это строка
false — это булево

(boolean) '0' — это булево
(boolean) '' — это булево

получается что: (boolean) '0' == (boolean) '' == false
0
Priest #
Все логично и правльно.
Свойство транзитивности не может оставаться строгим когда идет преобразование типов из-за возможных потерь информации.

'0'== false // true
false == '' // true
'0' == '' // false Строка содержащая 1 символ, не равна пустой строке.
Но
0 == '' // true


Потому что:
$a='0';
$b=false;
$c='';

to STRING:
a=0
b=
c=
to BOOL:
a=
b=
c=
to INT:
a=0
b=0
c=0
–3
fog #
Капец. Про неявное приведение типов вы никогда не слышали?
+1
davojan #
Конечно слышал. Это всего лишь забавное наблюдение по поводу транзитивности. Капец... :)
0
WanderingStar #
"Сам активно пишу на PHP."
Не надо. Ни одному человеку который учился не по книгам "PHP за 24 часа" даже в голову не прийдет такое сравнивать ибо результат вполне предсказуем.
–1
yelbota #
Занавес это переполнение памяти при использовании str_replace() в старых версиях. В новых не проверял, думаю поправили. Но там еще много таких багов.
0
kozak #
Видимо, стоит поменять пример с '0' == '' на 0 == '', а то действительно получается сравнение двух строк.
0
pietrovich #
угу, да только данные из $_ENV, $_SERVER, $_GET, $_POST etc. достаются строки (про массивы умолчим), и соответственно
$_GET['here_is_my_zero'] == '' будет работать как в примере...
0
pietrovich #
ух, какая полемика :)
про Java или C# такой спор в принципе не мог произойти, ибо сравнивать в них можно только одинаковые типы (даже при сравнении short и long IDE будет намекать на ошибку, а String'и в Java через "==" не сравнивают)...

а тут с одной стороны вроде как гибкий инструмент, а с другой "сдуру можно и хер сломать" :)

>даже в голову не прийдет такое сравнивать
прийдет или не прийдет дело десятое. это же иллюстрация :)
0
Varnak #
Что поделать, специфика слабо типизированного языка
0
WanderingStar #
Иллюстрация, простите, к чему? К тому что превосходно изложено в документации к языку или в Zend PHP5 Certification Study Guide? Мне сейчас лениво рыться в этом талмуде, но типизация в PHP там расписана довольно хорошо, при чем на первых страницах. Ссылки же на документацию были выше.

Это я к тому, что учить язык надо по вот таким источникам. Тогда и иллюстрировать ничего не прийдется. Те кто действительно знает PHP прекрасно понимают в чем фишка, и почему работает именно так. Те же кто знаком с ним по упомянутым мною выше "... за 24 часа" прочитают, забудут через 15 минут и уж тем более не извлекут никакого для себя урока.
0
gro #
Сдуру можно поломать всё что угодно.
0
pietrovich #
я о том же :)
+1
wambat #
Зато ПХП это глобально и надежно! (с) l.o.r.
+3
claustrofob #
аналогично:
'муха' == true
'слон' == true
'муха' == 'слон'
0
davojan #
класс :)
Ваш пример, в отличие от моего, можно размножить до бесконечности :)
Однако вероятность ошибки по неосторожности в случае с нулём и пустой строкой больше.
0
claustrofob #
По неосторожности ошибок можно нагородить где угодно. А в данном случае ошибка может возникнуть, когда вы работаете с переменными и точно неизвестно какого она типа. Тогда необходимо явно преобразовывать тип переменной:
$x == false; // true
false == $y; // true
$x == $y //???

тогда лучше так
intval($x) == intval($y)

или так
strval($x) == strval($y)
в зависимости от контекста
–1
kvas #
Хороший язык PHP, ничего не скажешь. Особенно то, что непустая строка может быть == false — это парни вообще отожгли.
0
claustrofob #
это неизбежные последствия нетипизированности языка. главное об этом помнить и грамотно пользоваться.
–3
kvas #
Ладно, буду помнить (читай "буду пользоваться более разумными языками" :).
0
Devgru #
разумность разумности рознь. если вы не готовы платить аккуратностью за гибкость — значит, что PHP не для вас, но никак не то что он неразумен.
–1
kvas #
Нет, не готов. Я люблю гибкость забесплатно, без кучи неочевидных граблей.
0
maserg #
там нет неочевидных граблей. всё четко расписно в мануале
0
gro #
Да пользуйтесь вы чем хотите.
Только зачем публично определять свою позу - все пхпшники в г-не, а я один в белом?
+2
bolk #
Вы, видимо, думаете, что где-то иначе?

mysql> SELECT '0'=FALSE FROM DUAL;
+-----------+
| '0'=FALSE |
+-----------+
| 1 |
+-----------+
1 row in set (0.00 sec)

mysql> SELECT FALSE='' FROM DUAL;
+----------+
| FALSE='' |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)

mysql> SELECT '0'='' FROM DUAL;
+--------+
| '0'='' |
+--------+
| 0 |
+--------+
1 row in set (0.00 sec)
0
deMone #
Последнее вполне нормально: оба операнда — строки, никаких преобразований типов не будет, а строки между собой не равны.
0
shuba #
Контекст, однако.
Фича известная.

И чего к PHP докопались? Тогда уж с Перла начните.
0
luf #
Как раз сегодня на работе обсуждали поднялась тема приведения типов в пыхе. По мотивам - написал в блоге. http://nordluf.blogspot.com/2007/10/string-to-int-voodoo.html
0
WanderingStar #
Кто вас вообще учил использовать Эхо для дебага???
0
Devgru #
*чисто для интереса*
а сколько и какие именно средства дебага на PHP вы сможете сходу назвать?
0
WanderingStar #
var_dump() справится с задачей значительно эфективнее и несомненно поможет автору найти ответы на мучающие его вопросы. Вы так не считаете?
0
luf #
Вы ошибаетесь: результат мне известен - boolean. Я ведь делаю не вывод значения переменной, а демонстрирую результат сравнения.
0
WanderingStar #
> демонстрирую результат сравнения (пост выше)
> displays structured information about one or more expressions (php.net)

А это не одно ли и то же? Как пожно предположить, цитата относится далеко не к описанию echo.

> результат мне известен
так обычно пишут, когда знают(!) не только тип данных возвращаемых операцией сравнения, но и результат этого сравнения. О вот он, как мне показалось ( "Это обьяснить и понять уже сложнее" (с) ) для вас немного остался загадкой.

П.С.: прошу извинить, если мой тон показался вам излишне резким. Ни в коем случае не хотел на вас "наезжать" ибо и сам на абсолютное знание не претендую.
0
luf #
Ну тип всегда - boolean. Проверить можно просто посмотрев что вернет gettype("0xff"==255), а так же все другие сравнения. Это будет string(7) "boolean".
А явное преобразование boolean в integer у меня пока не вызывает сомнение. Поэтому я пишу echo.
Кроме того, автоматически приписать в начале строки echo проще нежели писать более сложную регулярку для окружения результата var_dump'ом. ;)
Я ведь, ествественно, не так смотрел всё это - это просто минималистический тестовый пример.
0
WanderingStar #
Ваша запись:
echo (int)("0xff"==0)."\n";
echo (int)((int)"0xff"==0)."\n";
echo (int)("0xff"==255)."\n";

Моя запись:
var_dump("0xff"==0, (int)"0xff"==0, "0xff"==255);

Какую-какую, простите, регулярку писать?
0
luf #
Регулярку для обработки хлама который был, в вывод с var_dump ом.
0
Devgru #
да, вы правы, но мне просто интересно было, вдруг ещё что-то есть…
0
WanderingStar #
Ну есть еще print_r(), если тип данных не нужен. А вар_дамп даже Зендовцы используют в экзаменах, если мне память не изменяет. Все никак время не выкрою на ЗЦЕ себя попробовать ...
0
luf #
Как Вам, я уже понял. Лично мне удобнее пользоваться var_export'ом. Для меня он нагляднее + позволяет без мучений с ob_* функциями передавать эти дампы в переменных.
0
luf #
А это не дебаг: примеры написано исключительно для демонстрации.
0
WanderingStar #
Даже для демонстрации var_dump() подходит значительно лучше, поскольку показывает нам не только значение, но и тип. А ведь именно о приведении типов мы сейчас говорим.
0
WanderingStar #
Попробую вам объяснить то, что вам сейчас (судя по блогу) непонятно:

(int)("0xff"==0)
строка 0xff превосходно конвертируется в число в 16-ной форме. Далее приводится к десятичному 255. Это не равно нулю, а false при преобразовании в int становится нулем.

(int)((int)"0xff"==0)
Здесь интерпретатор не может преобразовать строку к 16-ричному виду, поскольку вы ему указываете на необходимость сразу преобразовать строку в интеджер. Используется явное преобразование, что дает нам 0, значит результат true, как следствие - 1

(int)("0xff"==255)
См. первое решение.
0
luf #
Мне непонятен тут исключительно один момент: почему преобразование в integer работает по разному. Когда сравнивается "0xff" и 255 - приведение в integer(255). В случае явного преобразования 0xff - в integer(0).
0
WanderingStar #
А вы воспользуйтесь intval() с указанием основания. И все будет замечательно.
А приводит оно так, ибо сказано: the default is base 10
0
luf #
Интересная мысль, которая мне не приходила в голову. Видимо, из-за ощущения, что попытка приведения строки к числу должна быть реализована всегда одинаково. Откуда берется base 16? Видимо проверяется содержание строки. Почему тогда нет этого при явном приведении к инту? Лично для меня x16, x10, x8, x2 - всё тот же родной int. Я хорошо понимаю откуда что берется, меня удивляет именно разница в поведении в момент приведения.
0
WanderingStar #
Могу предположить, что происходит так из-за того, что неявное преобразование использует функцию strtod из stdlib на которую они и ссылаются в мануале. Она превосходно конвертирует и 10, 16, бесконечность и NAN. В то время как явное преобразование с помощью intval реализовано у них своими силами, на что довольно таки прозрачно намекает документация, где сказано, что основание указывается необязательным параметром функции, в то время как strtod определяет его автоматически.
0
luf #
Именно об этом я и написал. Чтоб узнать каким именно образом происходит обработка явного и неявного приведения я в исходники всё таки не полезу, но да не суть важно. Собственно, моё удивление связанно как раз с тем, что оба эти, на мой взгляд одинаковые, операции реализованный по разному. Ни в коей мере не умаляя достоинств разработчиков, я считаю что это неверное решение.
0
WanderingStar #
"Это не баг, это фича" (с)
Соглашусь с тем, что это несколько странно. Но как уже здесь писали, хотя несколько по другому поводу - для хорошего(!) разработчика главное такие тонкости знать и уметь использовать себе во благо.
0
luf #
Угу. Как обычно и бывает - пришли к выводу что говорим об одном и том-же разными словами.

Кстати, одна из причин написать в блог развёрнуто и с примерами, была в том, что я хотел проиллюстрировать это поведение. Именно для того, о чём Вы написали выше (про разработчика). Собьсно тот пост вырос из развёрнутого обьяснения новенькому почему if ($rt=="0") {...} срабатывает, когда $rt==="all".
0
luf #
Ошибся. Правильно конечно же if ($rt==0) {...}
0
WanderingStar #
Вот здесь многое изложено со ссылками на более детальные пояснения по темам и с указаниями куда именно смотреть при желании найти еще более подробную информацию.
0
gro #
для людей писавших на нормальных языках

Так зачем вы вообще за PHP взялись, если он ненормальный?
0
luf #
Вы меня неверно поняли. Лично у меня нет никаких претензий к PHP5. Это один из немногих языков. на которых я продолжаю писать после знакомства с ним. Тем не менее, я об этом тоже немного писал в блоге, многие программисты на "нормальных" языках относятся к нему как к "недоязыку для дизайнеров". Я много обсуждал это со своими друзьями, но в результате мне остаётся только грустно иронизировать время от времени. Они всё понимают мозгом, но отказываются это признавать.
0
gro #
Тогда извините )
+1
WanderingStar #
Ответ скорее не автору топика, а многим из комментировавших.

Дело в том, что в PHP оператор == НЕ ЯВЛЯЕТСЯ оператором равенства. Он лишь означает equivalence операндов, что в переводе на русский означает "равнозначность", но отнюдь не "равенство". Вот так непонимание русского языка (не важно кем, переводчиком либо читателем) приводит к непониманию азбучных истин программирования.
0
Klaus #
На сколько мне не изменяет память, то при ТОЧНОМ сравнении нужно пользовать ===
0
WanderingStar #
Именно так. На удивление многим это тоже не оператор равенства. Это оператор "идентичности". И, вы будете смеяться, но мне попадалась на книжных полках макулатура (по другому назвать язык не поворачивается) в которой вообще об этом операторе и слова не было сказано.
0
Klaus #
Я учился по книге и там это было указано в «Золотых ошибках»
0
leemuar #
Я учился на слове "эквивалентность"
+1
ilya_ost #
отношение == (eq1), определенное на множестве строк, и отношение == (eq2) на множестве строк и булевых значений очевидно отношения разные. Каким образом отсутствие импликации: (a eq2 b И b eq2 c) -> a eq1 c влияет на транзитивность отношения eq1 или eq2 мне не понятно. И кстати в C++: 12 == true; 13 == true; 12 !=13, какой ужас!
0
gro #
Знаете, как ни странно, но в PHP 12 так же != 13.
Отношение == на множестве строк и булевых значений не определено, поэтому строка приводится к булевому значению и выполняется операция определенная на множестве булевых значений. Так же, как и в C++.
0
leemuar #
Весь секрет фокуса крутится вокруг _строковой константы_ '0', вводящей начинающего программиста в заблуждение.
Остальное уже было сказано.
0
hannimed #
Если строка '0' вводит программиста в заблуждение, то такому программисту пора подумать о покупке какой-нибудь книги.
А лучше выучить какой-нибудь типизированный язык для разнообразия.

Вообще если человек начинает программировать с PHP (!) - велика вероятность не стать хорошим программистом.

Этот топик во мне вызвал чувство деградации... сам пишу на PHP, т.к. работа вынуждает. Грустно. Эх... пойду что-ли Страуструпа почитаю...
0
artyfarty #
Да, пыхпых породил немало быдлокодеров.
Сам, сильно увлёкшись пхп, и забыв о типах, потом довольно болезненно начинал сишарп.
0
besisland #
Первое, что приходит в голову лично мне: "Это ж очевидно: конечно, не обладает!"
0
artyfarty #
Автоматическое преобразование типов хотя и радует нас такими сюрпризами, но немного почитав манов, да набравшись опыта, можно всё это предвидеть.

Зато не нужно парится о типах в процессе кодинга. PHP позволяет мне излагать свои мысли прямо по ходу их поступления, не отвлекаясь на объявления переменных, размышления о том, какой тип рациональнее. Меня не ставят в строгие границы, как это, например, обожает делать C#.
0
artyfarty #
И вообще, ситуация из приведённого примера абсолютно очевидна.

В первой ситуации строку сравнивают с булевым типом. Пхп преобразует строку в bool и сравнивает 0 ? false. Конечно же, равны.
Кстати, это популярный источник ошибок. Ошибки, основанные на этом равенстве я находил даже в IPB. А именно, когда программист хочет проверить, указана ли строка: if ( $string ) { .. } Очевидно, что если юзер напишет строку "0", то условие не выполнится. Благодаря этому, в недавней версии ИПБ нельзя было поставить личный статус "0".

Вторая ситуация очевидна.

В третьей ситуации сравниваются две строки. Никакого преобразования не происходит. Две строки нифига не одинаковые, следовательно false;
0
etc #
Никаких чудес, просто строка 0 не равна пустой строке.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.