Проблема с in_array
Недавно у меня возникла странная проблема с in_array
, которую я не могу понять.
например.
$a = array('a','b','c');
$b = array(1,2,3);
if (in_array(0,$a))
{
echo "a bingo!\n";
}
else
{
echo "a miss!\n";
}
if (in_array(0,$b))
{
echo "b bingo!\n";
}
else
{
echo "b miss!\n";
}
Я запустил его на своей лампе и получил
a bingo!
b miss!
Я прочитал руководство и установил третий параметр $strict
как true
, тогда он работал как ожидается. Но это означает, что мне всегда нужно установить строгий параметр как истинный при использовании in_array
? Предложения будут оценены.
Привет
Ответы
Ответ 1
Это означает, что вам нужно установить третий параметр true
, если вы хотите, чтобы сравнение не только сравнивало значения, но также и типы.
В противном случае существуют преобразования типов при выполнении сравнений - например, Преобразование строк в числа.
На самом деле in_array
без и со строгим - это просто та же разница, что и между ==
и ===
- см. Операторы сравнения.
Это преобразование, в большинстве случаев, работает нормально... Но не в том случае, если вы пытаетесь сравнить 0 со строкой, начинающейся с буквы: строка преобразуется в числовое значение, которое имеет значение 0 в качестве значения.
Ответ 2
Режим "по умолчанию" in_array
использует свободное сравнение, как ==
оператор сравнения. Это означает, что 0
сравнивается следующим образом:
var_dump(0 == 'a'); // bool(true)
var_dump(0 == 'b'); // bool(true)
var_dump(0 == 'c'); // bool(true)
Теперь оператор оператора сравнения ==
использует string преобразование в целое число до фактического сравнения значений:
Если вы сравниваете число со строкой или сравниваете числовые строки, то каждая строка преобразуется в число и выполняется сравнение численно.
И 'a'
, 'b'
и 'c'
преобразуются в 0
:
var_dump((int) 'a'); // int(0)
var_dump((int) 'b'); // int(0)
var_dump((int) 'b'); // int(0)
Но при использовании in_array
в строгом режиме (установите третий параметр в true) выполняется строгое сравнение (===
), это означает, что и значение, и тип должны быть равны:
var_dump(0 === 'a'); // bool(false)
var_dump(0 === 'b'); // bool(false)
var_dump(0 === 'c'); // bool(false)
Поэтому, когда вы используете in_array
в строгом режиме, вы получаете ожидаемый результат:
var_dump(in_array(0, $a, true)); // bool(false)
Ответ 3
В вашем первом примере каждое значение массива $a, при преобразовании в числовое, равно 0. Вот почему ваш первый пример приводит к "бинго".
Вам не нужно использовать строгий параметр, если вы знаете, что полагаетесь на неявное преобразование или что ваши типы данных одинаковы (например, поиск строки в массиве строк). В противном случае вы должны использовать строгий параметр, то же самое вы должны использовать === вместо == при сравнении двух значений, которые должны быть одного типа.