Php, in_array, значение 0

Я пытался понять поведение in_array в следующем сценарии:

 $arr = array(2 => 'Bye', 52, 77, 3 => 'Hey'); var_dump(in_array(0, $arr)); 

Возвращаемое значение in_array() имеет значение boolean. Как вы можете видеть, нет значения, равного 0 , поэтому, если кто-нибудь, пожалуйста, помогите мне понять, почему функция возвращает true?

Это известная проблема в комментариях к документации . Рассмотрим следующие примеры:

 in_array(0, array(42)); // FALSE in_array(0, array('42')); // FALSE in_array(0, array('Foo')); // TRUE 

Чтобы этого избежать, предоставьте третий параметр, true , разместив сравнение в строгом режиме, который будет не только сравнивать значения, но и типы:

 var_dump(in_array(0, $arr, true)); 

Существуют другие проблемы, которые не требуют, чтобы каждая проверка была помещена в строгом режиме:

 in_array($value, $my_array, empty($value) && $value !== '0'); 

Но почему?

Причиной всего этого является вероятное преобразование числа строк в число . Если мы попытаемся получить число из «Bye», нам присваивается 0 , это значение, которое мы запрашиваем для поиска.

 echo intval("Bye"); // 0 

Чтобы подтвердить это, мы можем использовать array_search для поиска ключа, связанного с соответствующим значением:

 $arr = array(2 => 'Bye', 52, 77, 3 => 'Hey'); echo array_search(0, $arr); 

В этом случае возвращаемый ключ равен 2 , что означает, что 0 находится в преобразовании Bye в целое число.

Попробуйте добавить третий параметр true (строгий режим) к вызову in_array .

Это результат плохого сравнения и жонглирования типов .

Свободное сравнение означает, что PHP использует == not === при сравнении элементов. == не сравнивает, что два типа переменных равны, только их значение, а === будет гарантировать, что они совпадают по типу и значению (например, сравните 0 == FALSE и 0 === FALSE ).

Итак, в основном, ваша функция in_array проверяет:

 0 == 'Bye' 0 == 'Hey' 0 == 77 

Обратите внимание, что 52 будет потерян из-за того, как вы создали свой массив.

Итак, обратите внимание, что если вы выполните:

 print (0 == 'Bye'); 

Вы получите 1. Видимо, PHP – это манипуляция типа «Bye» до 0, что то же самое, что и при передаче строки в int, например (int) 'string' будет равно 0. Конкретная ссылка из Преобразование строк в число doc (добавлено):

Значение задается начальной частью строки. Если строка начинается с действительных числовых данных, это будет используемое значение. В противном случае значение будет равно 0 (ноль) . Действительные числовые данные являются необязательным знаком, за которым следуют одна или несколько цифр (необязательно содержащие десятичную точку), за которыми следует необязательный показатель. Показателем является «e» или «E», за которым следует одна или несколько цифр.

По-видимому, целочисленный тип имеет приоритет над строковым типом (т. Е. Так же легко можно было бы провести сравнение путем литья int 0 в строку, которая затем вернет False). Это указано в операциях сравнения doc :

Если вы сравниваете число со строкой или сравниваете числовые строки, то каждая строка преобразуется в число, а сравнение выполняется численно.

Спасибо за интересный вопрос, который заставил меня сделать некоторые исследования и узнать что-то новое!

Предполагается, что in_array используется для индексированных массивов ([0], [1], [2] и т. д.), а не со словарем, который вы определили (хранилище значений ключа).

Если вы хотите проверить, содержит ли ваш массив $ arr '0', попробуйте вместо этого использовать функцию PHP array_key_exists – http://php.net/manual/en/function.array-key-exists.php .

 var_dump(array_key_exists(0, $arr));