Подтвердить что ты не робот

Проблема с 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? Предложения будут оценены.

Привет

4b9b3361

Ответ 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. Вот почему ваш первый пример приводит к "бинго".

Вам не нужно использовать строгий параметр, если вы знаете, что полагаетесь на неявное преобразование или что ваши типы данных одинаковы (например, поиск строки в массиве строк). В противном случае вы должны использовать строгий параметр, то же самое вы должны использовать === вместо == при сравнении двух значений, которые должны быть одного типа.