Мне часто приходится обрабатывать данные, которые могут быть либо массивом, либо нулевой переменной, и передавать некоторые данные для этих данных.
$values = get_values(); foreach ($values as $value){ ... }
Когда вы кормите foreach данными, которые не являются массивом, вы получаете предупреждение:
Предупреждение: неверный аргумент, предоставленный foreach () в […]
Предполагая, что невозможно get_values()
функцию get_values()
чтобы всегда возвращать массив (обратная совместимость, недоступный исходный код, по какой-либо другой причине), мне интересно, какой из них самый чистый и эффективный способ избежать этих предупреждений:
$values
массива $values
для массива foreach
с if
Лично я считаю, что это самый чистый – не уверен, что это самый эффективный, ум!
if (is_array($values) || is_object($values)) { foreach ($values as $value) { ... } }
Причина моего предпочтения заключается в том, что он не выделяет пустой массив, когда вам вообще нечего начинать.
Как насчет этого? много чистых и все в одной линии.
foreach ((array) $items as $item) { // ... }
Обычно я использую конструкцию, подобную этой:
/** * Determine if a variable is iterable. ie can be used to loop over. * * @return bool */ function is_iterable($var) { return $var !== null && (is_array($var) || $var instanceof Traversable || $var instanceof Iterator || $var instanceof IteratorAggregate ); } $values = get_values(); if (is_iterable($values)) { foreach ($values as $value) { // do stuff... } }
Обратите внимание, что эта конкретная версия не протестирована, ее набрали непосредственно в SO из памяти.
Изменить: добавлена проверка на перемещение
Пожалуйста, не зависеть от кастинга как решения , хотя другие предлагают это как допустимый вариант для предотвращения ошибки, это может привести к другому.
Имейте в виду : если вы ожидаете вернуть определенную форму массива, это может не сработать. Для этого требуются дополнительные проверки.
Например, приведение boolean в массив
(array)bool
не приведет к пусту массива, а массив с одним элементом, содержащим логическое значение как int:[0=>0]
или[0=>1]
.
Я написал быстрый тест, чтобы представить эту проблему . (Вот тест резервного копирования, если первый тестовый URL-адрес не работает.)
Включены тесты для: null
, false
, true
, class
, array
и undefined
.
Всегда проверяйте свой ввод перед его использованием в foreach. Предложения:
$array = is_array($var) or is_object($var) ? $var : [] ;
$array = is_array($var) or is_object($var) ? $var : [] ;
try{}catch(){}
array_key_exists
на определенном ключе или проверить глубину массива (когда он один!) . Попробуй это:
//Force array $dataArr = is_array($dataArr) ? $dataArr : array($dataArr); foreach ($dataArr as $val) { echo $val; }
😉
$values = get_values(); foreach ((array) $values as $value){ ... }
Проблема всегда равна нулю, а литье – это чистое решение.
Прежде всего, каждая переменная должна быть инициализирована. Всегда.
Кастинг не вариант.
если get_values (); может возвращать переменную типа, это значение должно быть проверено, конечно.
Более сжатое расширение кода @ Kris
function secure_iterable($var) { return is_iterable($var) ? $var : array(); } foreach (secure_iterable($values) as $value) { //do stuff... }
особенно для использования кода внутри шаблона
<?php foreach (secure_iterable($values) as $value): ?> ... <?php endforeach; ?>
foreach ($arr ? $arr : [] as $elem) { // Does something }
Это не проверяет, является ли это массивом, но пропускает цикл, если переменная имеет значение null или пустой массив.
Если вы используете php7 и хотите обрабатывать только неопределенные ошибки, это самый чистый IMHO
$array = [1,2,3,4]; foreach ( $array ?? [] as $item ) { echo $item; }
Я не уверен, что это так, но эта проблема возникает несколько раз при переносе сайтов WordPress или миграции динамических сайтов в целом. Если это так, убедитесь, что хостинг, на котором выполняется миграция, использует ту же версию PHP, которую использует ваш старый сайт.
Если вы не переносите свой сайт, и это просто проблема, возникшая при попытке обновления до PHP 5. Это позаботится о некоторых из этих проблем. Может показаться глупым решением, но сделал трюк для меня.
Исключительный случай для этого уведомления возникает, если вы устанавливаете массив в null внутри цикла foreach
if (is_array($values)) { foreach ($values as $value) { $values = null;//WARNING!!! } }
Похоже, что есть отношение к окружающей среде:
У меня был «недопустимый аргумент, предоставленный foreach ()», ошибка только в среде dev, но не в prod (я работаю на сервере, а не на localhost).
Несмотря на ошибку, var_dump указал, что массив там хорошо (в обоих случаях – приложение и dev).
Значение if (is_array($array))
вокруг foreach ($array as $subarray)
решило проблему.
Извините, что я не могу объяснить причину, но поскольку мне потребовалось некоторое время, чтобы понять решение, я подумал о том, чтобы лучше поделиться этим как наблюдением.
предупреждение неверный аргумент, предоставленный для твитов foreach (). идти к . / WP-содержание / плагины / дисплей-твиты-PHP
вставьте это устройство в линию номер 591. Он будет работать отлично
if (is_array($tweets)){ foreach ( $tweets as $tweet ) { ... } }
Я буду использовать комбинацию пустых, isset и is_array как
$array = ['dog', 'cat', 'lion']; if(!empty($array) && isset($array) && is_array($array){ //loop foreach ($array as $values) { echo $values; } }
Используйте функцию is_array, когда вы передадите массив в цикл foreach.
if (is_array($your_variable)) { foreach ($your_variable as $item) { //your code } }
Как насчет этого решения:
$type = gettype($your_iteratable); $types = array( 'array', 'object' ); if (in_array($type, $types)) { // foreach code comes here }
я бы сделал то же самое, что и Энди, но использовал «пустую» функцию.
вот так:
if(empty($yourArray)) {echo"<p>There's nothing in the array.....</p>";} else { foreach ($yourArray as $current_array_item) { //do something with the current array item here } }