Неверный аргумент поставляются для foreach()



мне часто случается обрабатывать данные, которые могут быть либо массивом, либо нулевой переменной, и кормить некоторые foreach С этими данными.



$values = get_values();

foreach ($values as $value){
...
}


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




предупреждение: неверный аргумент поставляются для foreach() в [...]




предполагая, что это не возможно, чтобы рефакторинг get_values() функция, чтобы всегда возвращать массив (обратная совместимость, недоступный исходный код, независимо от других причин), мне интересно, какой самый чистый и эффективный способ избежать этих предупреждений:




  • литье $values в массиве

  • инициализации $values в массиве

  • упаковка foreach С if

  • другое (пожалуйста, предложите)

2098   18  

18 ответов:

лично я считаю, что это самый чистый - не уверен, что это самый эффективный, ум!

if (is_array($values) || is_object($values))
{
    foreach ($values as $value)
    {
        ...
    }
}

причина моего предпочтения заключается в том, что он не выделяет пустой массив, когда вам все равно нечего начинать.

Как насчет этого? много чище и все в одну линию.

foreach ((array) $items as $item) {
 // ...
 }

Я обычно использую конструкцию, подобную этой:

/**
 * Determine if a variable is iterable. i.e. 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 из памяти.

Edit: добавил проходимым Регистрация

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

имейте в виду: если вы ожидаете, что будет возвращена определенная форма массива, это может привести к ошибке. Для этого требуется больше проверок.

например, приведение логического значения к массиву (array)bool, будет не результат в пустой массив, а массив с одним элементом содержит логическое значение в виде int:[0=>0] или [0=>1].

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

включены тесты для: null,false,true, a class, an array и undefined.


всегда проверяйте входные данные, прежде чем использовать его в foreach. Предложения:

  1. быстрая проверка типа:$array = is_array($var) or is_object($var) ? $var : [] ;
  2. введите массивы намеков в методах перед использованием foreach и С указанием типов возвращаемых
  3. обертывание foreach внутри if
  4. используя try{}catch(){} блоки
  5. проектирование правильного кода / тестирование перед выпуском продукции
  6. для проверки массива на правильность формы можно использовать array_key_exists на определенном ключе,или проверить глубину массива (когда он один !).
  7. всегда извлекать вспомогательные методы в глобальное пространство имен таким образом, чтобы уменьшить дублирование кода

попробуйте это:

//Force array
$dataArr = is_array($dataArr) ? $dataArr : array($dataArr);
foreach ($dataArr as $val) {
  echo $val;
}

;)

$values = get_values();

foreach ((array) $values as $value){
  ...
}

проблема всегда null и литье на самом деле является чистящим решением.

во-первых, каждая переменная должна быть инициализирована. Всегда.
Кастинг-это не вариант.
если get_values (); может возвращать переменную другого типа, это значение должно быть проверено, конечно.

более краткое расширение @Крис кода

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 
}

Это не проверяет, является ли он массивом, но пропускает цикл, если переменная равна нулю или пустому массиву.

Если вы используете php7 и хотите обрабатывать только неопределенные ошибки, это самый чистый IMHO

$array = [1,2,3,4];
foreach ( $array ?? [] as $item ) {
  echo $item;
}

Я не уверен, что это так, но эта проблема, похоже, возникает несколько раз при миграции сайтов wordpress или миграции динамических сайтов в целом. Если это так, убедитесь, что хостинг, на который вы переходите, использует ту же версию PHP, что и ваш старый сайт.

Если вы не переносите свой сайт, и это просто проблема, которая возникла, попробуйте обновить PHP 5. Это решает некоторые из этих проблем. Может показаться глупым решением, но сделал трюк для меня.

исключительный случай для этого уведомления происходит, если вы устанавливаете array в null внутри цикла foreach

if (is_array($values))
{
    foreach ($values as $value)
    {
        $values = null;//WARNING!!!
    }
}

Как насчет такого решения:

$type = gettype($your_iteratable);
$types = array(
    'array',
    'object'
);

if (in_array($type, $types)) {
    // foreach code comes here
}

там, кажется, также есть отношение к окружающей среде:

у меня была эта ошибка" недопустимый аргумент, предоставленный foreach () " только в среде dev, но не в prod (я работаю на сервере, а не на localhost).

несмотря на ошибку var_dump указал, что массив был хорошо там (в обоих случаях приложение и dev).

The if (is_array($array)) вокруг foreach ($array as $subarray) решена проблема.

Извините, что я не могу объяснить причину, но так как мне потребовалось некоторое время, чтобы подумайте о решении, которое я думал о том, чтобы лучше поделиться этим в качестве наблюдения.

Я буду использовать комбинацию empty, 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
}
}

предупреждение недопустимый аргумент, предоставленный для foreach () отображения твитов. перейдите в раздел " / wp-content / plugins / display-tweets-php ". Затем вставьте этот код в строку номер 591, он будет работать отлично.

if (is_array($tweets)){  
        foreach ( $tweets as $tweet ) 
    {
        ...
    }
}

Я бы сделал то же самое, что и Энди, но я бы использовал "пустую" функцию.

вот так:

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
  } 
}

Comments

    Ничего не найдено.