Я видел этот небольшой фрагмент кода, который уклоняется от моего понимания:
<?php
$a = '0e462097431906509019562988736854';
$b = '0e830400451993494058024219903391';
var_dump($a == $b);
Который будет выводить:
bool(true)
Я понимаю что при использовании ==
PHP попытается выполнить нечеткое сравнение, тихо конвертируя между типами, чтобы выполнить сравнение. Что я не Понимание — почему PHP, кажется, думает, что эти две строки одинаковы. Я бы подумал с $a
а также $b
являются строками, что преобразование типов не требуется.
Что я не понимаю?
Я думаю, что эта статья объясняет это довольно хорошо:
Операторы сравнения приведения типов преобразуют числовые строки в числа
Просто процитирую основной вопрос здесь:
В соответствии с php language.operators.comparison, операторы сравнения приведения типов приведут оба операнда к плавающим, если они оба будут выглядеть как числа, даже если они оба уже являются строками:
где оба strings
используют экспоненциальную запись, поэтому обрабатываются как числовые строки, что делает свободное сравнение (==
), приведите эти strings
в floats
прежде чем на самом деле «слабо» сравнивать их.
В качестве лучшей практики и для предотвращения непредвиденного поведения всегда старайтесь использовать равенство идентичности (===
), особенно когда имеешь дело с strings
PHP пытается преобразовать в тип float, потому что строка начинается с 0. Она останавливается после 0, потому что следующий символ не является числом. То же самое происходит, когда вы используете приведение типов для преобразования научной нотации в целое число:
$x = (float)"12E-1x"; // $x == 1.2
$x = (int)"12E-1x"; // $x == 12 (stops at E because it's not an integer)
Это не совсем ответ, но если вы попробуете:
$a = '0e4620974319065090195629887368549';
$b = '0e8304004519934940580242199033918';
echo floatval($a) . '<br>' . floatval($b);var_dump($a == $b);
Ты получаешь:
0
0
BOOL (истина)
Теперь, если вы попробуете:
$a = '0e4620974319065090195629887368549';
$b = '1e8304004519934940580242199033918';
echo floatval($a) . '<br>' . floatval($b);var_dump($a == $b);
Ты получаешь:
0
INF
BOOL (ложь)
Я предполагаю, что PHP преобразует строки в числа с плавающей точкой и выдает результат сравнения, используя полученные значения с плавающей точкой, что в любом случае неверно, но это уже другая история.
В официальной документации проверка на равенство между двумя переменными производится следующим образом:
$a == $b # Equal TRUE if $a is equal to $b after type juggling.
Пример :
$a = 13; # integer type
$b = "13"; # string type
var_dump($a == $b); # will say TRUE, because juggling was made
var_dump($a === $b); # will say FALSE, because PHP will also evaluate the type of variables :)