Имеем php 5.5.9 Пишем вот такой код: Код (Text): $test = function($a=0, $b=0){ print_r([($a==$b), ($a=='test'), ($b=='test')]); return null; }; $test(1,2); $test(1); По идее мы должны и в первом и во втором случае получить во всех условиях false, но не тут то было. По крайней мере у меня на 5.5.9 выводит следующее: Код (Text): Array ( [0] => [1] => [2] => ) Array ( [0] => [1] => [2] => 1 ) Таким образом, сравнения не переданного аргумента с любым значение выдает true. Скажите, коллеги, у вас на других версиях то же самое? И если да, то почему так? Может я что-то не понимаю? В комментах оставьте версию и результат теста, пжлст.
ну мне кажется тут не от версии зависит, а так 5.4 вроде. --- Добавлено --- и не в стандартном аргументе дело PHP: var_dump( 0 == 'test' ); // true
Судя по всему это фича динамической типизации. При сравнении Пых делает из стрингов инт. Код (Text): php > var_dump( 'test' == 0 ); bool(true) php > var_dump( '1test' == 0 ); bool(false) php > var_dump( '1test' == 1 ); bool(true) php > var_dump( 'test' == 1 ); bool(false) А теперь вопрос: А почему не наоборот? почему не int переводится в string, что более логично?
Не все так просто. В пхп многие входные данные - строки, даже если это числа (_GET, база данных и т.п.) Пхп хотел дать более простой механизм работы с такими числами. И если с равенством все более-менее, то с неравенствами - все сложнее. Ибо если сравнивать "5" и "10" как строки - то "5" больше! (см. жаваскрипт "5" > "10" - true). По-этому, PHP старается определить случаи, когда сравнивают числа. Такими маркерми являются два случая - если оба аргумента - numeric (т.е. строки с числами) или если один из аргементов - integer. Предполагается, что если уж написали в одной части integer - то точно хотят работы с числами, а не со строками.
А на самом деле лучше и не будет Ну вот есть у нас 5 > "test". Исключение не выход, у нас слабая типизация. И или мы приводим 5 к строке, или test к числу. Если не думать головой - оба варианта хреновые ибо дают неожиданные результаты. Если думать - то определить результат такого на глаз легче, когда test приводим к нулю. Не говоря уже о возможностях проверок if ($_GET['number'] > 0) .... - всякий введенный мусор не пройдет такие проверки. === бездумно тоже не вариант PHP: class A { const FIVE = 5; } if ($_GET['five'] === A::FIVE) ... // oops, false Т.е. все-равно нужно думать о типах. == в большинстве случаев удобнее оказывается. В общем единственный выход - отказываться от слабой типизации вообще, а это тянет за собой статическую, а в идеале еще и явную типизацию... в общем другой язык.
В том то и проблема, что на грабли эти наступил, когда проверял, что второй аргумент пустой (а он может выть 0-99 или all ) Так вот передаю я значение all а у меня срабатывает условие if ($arg2 == 0). Я сорок минут пытался отдуплить как вообще такое может происходить, так как мыслил в рамках равенства неравенства. Спасибо за пояснения