В PHP почему первые два из следующего утверждения оценивают true?
<?php if("00e0" == "00e1") { echo 'matches (a)'; } else { echo 'failed (a)'; } if("00e1" == "00e9") { echo 'matches (b)'; } else { echo 'failed (b)'; } if("00e2" == "00ea") { echo 'matches (c)'; } else { echo 'failed (c)'; } ?>
Если запустить, это вернет следующее:
matches (a) matches (b) failed (c)
Любая строка между «00e0», «00e1», «00e2» .. «00e9» даст значение true по сравнению с другой строкой «00e (0-9)».
Это потому, что строки, которые являются допустимыми значениями с плавающей запятой, интерпретируются как таковые.
Например, 00e0
эквивалентно 0 x 10 0
и 00e9
эквивалентно 0 x 10 9
, оба из которых равны нулю и, следовательно, равны друг другу.
Однако, поскольку 00ea
не является допустимым числом с плавающей запятой, оно обрабатывается по-разному.
Аналогичный эффект можно увидеть с помощью:
echo "01e2" - "01e1";
который выводит 90
потому что это то же самое, что 1 x 10 2 - 1 x 10 1
, или 100 - 10
.
Это поддерживается PHP doco (курсив мой):
Если вы сравниваете число со строкой или сравниваете числовые строки, то каждая строка преобразуется в число, а сравнение выполняется численно.
Этот параграф ссылается на другую страницу, в которой объясняются правила преобразования, если это произойдет:
Если строка не содержит символов «.», «E» или «E», а числовое значение вписывается в ограничения типа целочисленного типа (как определено PHP_INT_MAX), строка будет оцениваться как целое число. Во всех остальных случаях он будет оцениваться как плавающий.
Если вы хотите избежать этого поведения, в этой первой ссылке есть примечание, в котором говорится, что вы должны использовать ===
вместо:
Преобразование типа не происходит, когда сравнение === или! ==, поскольку это предполагает сравнение типа, а также значения.