Маленький пост о том, как поиметь проблем на ровном месте из-за неявного преобразования данных из одного типа в другой.
Допустим, у вас есть такой простенький код:
Видим вывод:
Возникает закономерный вопрос - почему? Мы же ожидали, что выведется только ключ
Давайте копнем чуть глубже и модифицируем код проверки:
Видим вывод:
Что мы видим? Что ключ первого элемента массива вместо типа строка (
Это стандартное поведение ключей типа строка, отмеченное в официальном руководстве. Получаем, что на первой итерации цикла мы сравниваем целое число
Казалось бы - строка
Что можно сказать в заключение:
P.S. Интересно, предложат и заапрувят ли когда-нибудь rfc, который сделает оба сравнения (
Допустим, у вас есть такой простенький код:
$a = ['1' => 'v1', '1-2' => 'v2', '1-3' => 'v3'];
$search = '1-2';
foreach ($a as $key => $value) {
if ($key == $search) {
echo 'Key found: ' . $key . PHP_EOL;
}
}
Видим вывод:
Key found: 1
Key found: 1-2
Возникает закономерный вопрос - почему? Мы же ожидали, что выведется только ключ
1-2
. Откуда же в выводе взялся ключ 1
?Давайте копнем чуть глубже и модифицируем код проверки:
if ($key == $search) {
var_dump($key, $search);
echo PHP_EOL;
}
Видим вывод:
int(1)
string(3) "1-2"
string(3) "1-2"
string(3) "1-2"
Что мы видим? Что ключ первого элемента массива вместо типа строка (
string
) стал типом целое число (integer
).Это стандартное поведение ключей типа строка, отмеченное в официальном руководстве. Получаем, что на первой итерации цикла мы сравниваем целое число
1
со строкой 1-2
. Немного неожиданно.Казалось бы - строка
1-2
уж никак не может быть равна целому числу 1
. Однако, правила сравнения разных типов (также отраженные в официальном руководстве, таблица Сравнение различных типов) сообщают, что при сравнении числа и строки, строка приводится к числу. И по правилам приведения к числу (опять же описанным к официальном руководстве) мы получаем, что строка 1-2
приводится к числу 1
. А уж 1
точно равно 1
.Что можно сказать в заключение:
- используйте
===
вместо==
- почаще читайте официальное руководство.
P.S. Интересно, предложат и заапрувят ли когда-нибудь rfc, который сделает оба сравнения (
===
и ==
) строгими?