Invalid argument supplied for foreach in ошибка

It often happens to me to handle data that can be either an array or a null variable and to feed some foreach with these data.

$values = get_values();

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

When you feed a foreach with data that are not an array, you get a warning:

Warning: Invalid argument supplied for foreach() in […]

Assuming it’s not possible to refactor the get_values() function to always return an array (backward compatibility, not available source code, whatever other reason), I’m wondering which is the cleanest and most efficient way to avoid these warnings:

  • Casting $values to array
  • Initializing $values to array
  • Wrapping the foreach with an if
  • Other (please suggest)

Geoffrey Hale's user avatar

asked Apr 13, 2010 at 13:48

Roberto Aloi's user avatar

Roberto AloiRoberto Aloi

30.5k21 gold badges74 silver badges112 bronze badges

1

Personally I find this to be the most clean — not sure if it’s the most efficient, mind!

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

The reason for my preference is it doesn’t allocate an empty array when you’ve got nothing to begin with anyway.

vlasits's user avatar

vlasits

2,2151 gold badge15 silver badges27 bronze badges

answered Apr 13, 2010 at 13:51

Andy Shellam's user avatar

Andy ShellamAndy Shellam

15.4k1 gold badge27 silver badges41 bronze badges

10

How about this one? lot cleaner and all in single line.

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

answered Apr 8, 2015 at 17:08

Ajith R Nair's user avatar

Ajith R NairAjith R Nair

2,1721 gold badge14 silver badges10 bronze badges

5

I usually use a construct similar to this:

/**
 * 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...
    }
}

Note that this particular version is not tested, its typed directly into SO from memory.

Edit: added Traversable check

answered Mar 27, 2013 at 9:30

Kris's user avatar

8

Please do not depend on casting as a solution,
even though others are suggesting this as a valid option to prevent an error, it might cause another one.

Be aware: If you expect a specific form of array to be returned, this might fail you. More checks are required for that.

E.g. casting a boolean to an array (array)bool, will NOT result in an empty array, but an array with one element containing the boolean value as an int: [0=>0] or [0=>1].

I wrote a quick test to present this problem.
(Here is a backup Test in case the first test url fails.)

Included are tests for: null, false, true, a class, an array and undefined.


Always test your input before using it in foreach. Suggestions:

  1. Quick type checking: $array = is_array($var) or is_object($var) ? $var : [] ;
  2. Type hinting arrays in methods before using a foreach and specifying return types
  3. Wrapping foreach within if
  4. Using try{}catch(){} blocks
  5. Designing proper code / testing before production releases
  6. To test an array against proper form you could use array_key_exists on a specific key, or test the depth of an array (when it is one !).
  7. Always extract your helper methods into the global namespace in a way to reduce duplicate code

Community's user avatar

answered Sep 26, 2015 at 17:54

AARTT's user avatar

AARTTAARTT

5035 silver badges8 bronze badges

Try this:

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

;)

answered Jun 12, 2014 at 23:06

Gigoland's user avatar

GigolandGigoland

1,22912 silver badges10 bronze badges

1

All answers provided above are essentially just error suppression.

Your PHP is telling you that you are trying to use a variable of incorrect type, and there is possibly an error. but all answers provided are just brushing this message off.

Your best bet is to initialize every variable before use. And to make return types strict and explicit. You must ask yourself, WHY get_values() is returning anything than array? Why it cannot be made to return just an empty array, if no data found? Surely it can be.

answered Apr 13, 2010 at 14:11

Your Common Sense's user avatar

Your Common SenseYour Common Sense

157k40 gold badges213 silver badges339 bronze badges

3

$values = get_values();

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

Problem is always null and Casting is in fact the cleaning solution.

answered Mar 2, 2016 at 14:25

boctulus's user avatar

boctulusboctulus

3958 silver badges15 bronze badges

0

foreach ($arr ?: [] as $elem) {
    // Do something
}

This doesen’t check if it is an array, but skips the loop if the variable is null or an empty array.

Update from PHP 7.0 you should use the null coalescing operator:

foreach ($arr ?? [] as $elem) {
    // Do something
}

This would solve the warning mentioned in the comment (here a handy table that compares ?: and ?? outputs).

answered Dec 18, 2015 at 9:31

T30's user avatar

T30T30

11.2k7 gold badges53 silver badges57 bronze badges

1

If you’re using php7 and you want to handle only undefined errors this is the cleanest IMHO

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

answered Aug 9, 2016 at 15:27

Edwin Rodríguez's user avatar

0

More concise extension of @Kris’s code

function secure_iterable($var)
{
    return is_iterable($var) ? $var : array();
}

foreach (secure_iterable($values) as $value)
{
     //do stuff...
}

especially for using inside template code

<?php foreach (secure_iterable($values) as $value): ?>
    ...
<?php endforeach; ?>

Community's user avatar

answered Apr 23, 2015 at 12:38

HongKilDong's user avatar

HongKilDongHongKilDong

1,2763 gold badges16 silver badges23 bronze badges

1

Warning invalid argument supplied for foreach() display tweets.
go to /wp-content/plugins/display-tweets-php.
Then insert this code on line number 591, It will run perfectly.

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

Nik's user avatar

Nik

2,8452 gold badges25 silver badges25 bronze badges

answered Apr 10, 2015 at 7:59

Saad Khanani's user avatar

0

There seems also to be a relation to the environment:

I had that «invalid argument supplied foreach()» error only in the dev environment, but not in prod (I am working on the server, not localhost).

Despite the error a var_dump indicated that the array was well there (in both cases app and dev).

The if (is_array($array)) around the foreach ($array as $subarray) solved the problem.

Sorry, that I cannot explain the cause, but as it took me a while to figure a solution I thought of better sharing this as an observation.

answered Feb 22, 2015 at 11:36

araldh's user avatar

Exceptional case for this notice occurs if you set array to null inside foreach loop

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

answered Jan 18, 2016 at 9:24

Farid Movsumov's user avatar

Farid MovsumovFarid Movsumov

12.2k8 gold badges71 silver badges97 bronze badges

This warning is happening because the array that you want use is empty, you can use of below condition:

if ($your_array != false){
   foreach ($your_array as $value){
         echo $value['your_value_name'];
    }
}

answered May 12, 2022 at 6:24

Mohamad Shabihi's user avatar

Use is_array function, when you will pass array to foreach loop.

if (is_array($your_variable)) {
  foreach ($your_variable as $item) {
   //your code
}
}

answered Oct 21, 2017 at 21:46

Billu's user avatar

BilluBillu

2,68326 silver badges47 bronze badges

How about this solution:

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

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

answered Nov 1, 2017 at 12:04

Julian's user avatar

JulianJulian

4,3265 gold badges38 silver badges51 bronze badges

What about defining an empty array as fallback if get_value() is empty?
I can’t think of a shortest way.

$values = get_values() ?: [];

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

answered Mar 18, 2019 at 22:27

Quentin Veron's user avatar

Quentin VeronQuentin Veron

3,0441 gold badge13 silver badges31 bronze badges

I’ll use a combination of empty, isset and is_array as

$array = ['dog', 'cat', 'lion'];

if (!empty($array) && isset($array) && is_array($array) {
    //loop
    foreach ($array as $values) {
        echo $values; 
    }
}

Nik's user avatar

Nik

2,8452 gold badges25 silver badges25 bronze badges

answered Oct 6, 2017 at 17:10

Rotimi's user avatar

RotimiRotimi

4,7634 gold badges18 silver badges27 bronze badges

<?php
 if (isset($_POST['checkbox'])) {
    $checkbox = $_POST['checkbox'];
    foreach ($checkbox as $key) {
       echo $key . '<br>';
    }
}

?>
    <input type="checkbox" name="checkbox[]" value="red">red <br>
    <input type="checkbox" name="checkbox[]" value="green">green <br>

sajadsalimian's user avatar

answered Sep 30, 2012 at 17:40

as_bold_as_love's user avatar

2

Разрабатывая свой код на PHP, программист может столкнуться с сообщением об ошибке «Invalid argument supplied for foreach in…». После данного сообщения обычно следует указание на её конкретику, к примеру, «/modules/tasks/todo_tasks_sub.php on line 121». Ошибка обычно обусловлена спецификой имеющегося отрезка кода, и требует проверки особенностей использования в нём переменных. Давайте разберём факторы появления ошибки, и как её можно исправить.

Ошибка Invalid argument

Содержание

  1. Причины появления Invalid argument supplied for foreach
  2. Как исправить ошибку «Invalid argument supplied for foreach in»
  3. Ошибка в WordPress
  4. Заключение

Причины появления Invalid argument supplied for foreach

Рассматриваемая ошибка обычно возникает в ситуации, когда переменная, которую foreach пытается выполнить (повторить) не является массивом. К примеру, вы передаёте в цикл не массив, а скаляр, или вы задействуйте двойной массив, и забыли определить, как выбирается индекс.

Давайте допустим, что мы имеем функцию с именем get_user_posts. Эта функция должна возвращать массив комментариев пользователя. Однако если комментариев нет, функция возвращает логическое значение FALSE.

Код PHP

В приведенном выше отрезке кода мы предположили, что переменная $ posts всегда будет массивом. Однако, если функция get_user_posts возвращает логическое значение FALSE, то цикл foreach не будет работать, и PHP выведет следующее сообщение об ошибке:

Warning: Invalid argument supplied for foreach() on line 7

Как же решить указанную проблему? Давайте разбираться.

Как исправить ошибку «Invalid argument supplied for foreach in»

Решение зависит от того, для чего предназначен ваш код. То есть, если функция get_user_posts всегда должна возвращать массив, то, очевидно, вам необходимо выяснить, почему она возвращает логическое значение FALSE или значение NULL. Причиной этому может быть несколько вещей:

  • Не удалось объявить пустой массив «по умолчанию» (default);
  • Сбой запроса к базе данных;
  • Массив перезаписывается или сбрасывается. Это часто происходит в скриптах с большим количеством массивов, когда имеются ограничения памяти, а разработчик вынужден сбрасывать массивы, с которыми он или она закончили работу.

Просматривая чей-либо код, мы можем столкнуться с API и функциями, которые возвращают значение FALSE, когда результаты отсутствуют. Если это так, то вы можете добавить следующую проверку в ваш код:

Пример кода PHP

Выше мы используем функцию is_array, чтобы проверить, является ли $posts массивом. И это мы делаем ДО того, как пытаемся зациклить его с помощью конструкции foreach. Как мы уже писали, все зависит от того, каково предназначение вашего скрипта. Добавление проверки is_array неразумно в ситуации, когда есть вопросы о том будет ли переменная массивом. Ведь вы будете скрывать ошибку, которой не должно существовать.

Ошибка в WordPress

Также рассматриваемая ошибка может появляться при работе сайтов на WordPress. Проблема вызвана тем, что WP_Block_Parser выполняет несколько строковых манипуляций с substr () и strlen (), предполагая, что они работают с одиночными байтами, а не с многобайтовыми последовательностями.

Решить ошибку Invalid argument supplied for foreach в WordPress помогает изменение значения настройки mbstring.func_overload на 0 (обычно стоит 2). Сохраните произведённые изменения, и попытайтесь перейти на проблемную ранее страницу.

Если это не помогло, попробуйте скачать Вордпресс 4.9.5, вытянуть из него папку wp-includes, и скопировать в аналогичную папку на вашем хостинге. После этого WordPress может предложить обновить ваши базы данных, соглашайтесь, и всё заработает после очистки кэша.

Заключение

Ошибка «Invalid argument supplied for foreach in…» в коде PHP обычно вызвана переменной, не являющейся массивом. Последнюю пытается выполнить foreach, но безуспешно. Для решения возникшей проблемы можно добавить функцию is_array (она проверит, является ли переменная массивом). Также может порекомендовать общий ознакомительный материал на сайте phpfaq.ru, где детально разобрано, как найти ошибку в созданном вами коде.

The «invalid argument supplied for foreach()» error can trigger once the built-in foreach of PHP attempts to iterate over a data structure, which is not recognized as an array or an object.

Let’s check out a code snippet:

<?php

function getList()
{
  // Several errors occurs here and instead of
  // an array/list, a boolean FALSE is returned.
  return false;
}

// Retrieve the array from a function call.
$myList = getList();

//Loop through the $myList array.
foreach ($myList as $arrayItem) {
  //Do something.
}

?>

The output of this code will lead to the «invalid argument supplied for foreach()» error.

Let’s figure out why it happens and how to resolve the error.

The main cause of the error is that instead of an array a boolean value is returned by the getlist() function.

It is essential to note that the foreach() command is capable of iterating merely over objects or arrays.

The resolution to this error can be quite simple. All you need is to check before the foreach command for being circumvented.

The code below clearly shows how to resolve the error:

<?php

function getList()
{
  // Assume some error occurs here and instead of
  // a list/array, a boolean FALSE is returned.
  return false;
}

// Get the array from a function call.
$myList = getList();

// Check if $myList is indeed an array or an object.
if (is_array($myList) || is_object($myList)) {
  // If yes, then foreach() will iterate over it.
  foreach ($myList as $arrayItem) {
    //Do something.
  }
}
// If $myList was not an array, then this block is executed.
else {
  echo "Unfortunately, an error occurred.";
}

?>

Another way is to use is_iterable which was introduced in PHP 7.1.

<?php

function getList()
{
  // Assume some error occurs here and instead of
  // a list/array, a boolean FALSE is returned.
  return false;
}

// Get the array from a function call.
$myList = getList();

// Check if $myList is indeed an array or an object.
if (is_iterable($myList)) {
  // If yes, then foreach() will iterate over it.
  foreach ($myList as $arrayItem) {
    //Do something.
  }
}
// If $myList was not an array, then this block is executed.
else {
  echo "Unfortunately, an error occurred.";
}

?>

In PHP, the foreach() construct allows iterating over arrays straightforwardly.

It only operates on objects and array. After using it on a variable with a different data type, it leads to an error.

In PHP 5, once foreach begins to execute first, the internal array pointer is reset to the array’s first element automatically. Hence, there is no necessity in calling the reset() function before the foreach loop.

To get more information about foreach() in PHP, you can refer to this source.

<?php

function getList () {

// Assume some error occurs here and instead of

// a list/array, a boolean FALSE is returned.

return false;

}

// Get the array from a function call.

$myList = getList();

// Check if $myList is indeed an array or an object.

if (is_array($myList) || is_object($myList))

{

// If yes, then foreach() will iterate over it.

foreach($myList as $arrayItem){

//Do something.

}

}

else // If $myList was not an array, then this block is executed.

{

echo "Unfortunately, an error occured.";

}

?>

Benjamin Crozat
— Updated on Nov 23, 2022

Artboard

Hundreds of developers subscribed to my newsletter.
Join them and enjoy free content about the art of crafting websites!

Powered by

Why does the “Invalid argument supplied for foreach()” warning occurs?

The “Invalid argument supplied for foreach()” warning occurs when you try to iterate over something other than an array or an object.

On PHP 8+, the warning has been rewritten to “foreach() argument must be of type array|object”.

Whatever version of PHP you’re on, you need to ensure that an array or an object is always passed to foreach.

Use the null coalescing operator

When you cannot be certain that you’ll get an array or null, you can use the null coalescing operator to ensure an array will always be passed to foreach.

foreach ($value ?? [] as $item) {

}

Check if your value is iterable

One of the safest way to go is to use the is_iterable() function. It checks for either:

  • An array;
  • A Traversable object.

if (is_iterable($value)) {

foreach ($value as $item) {

}

}

Use Laravel’s collections

If you’re using Laravel, you can use collections to wrap your arrays and work with safer code.

Let’s say you’re refactoring a poor-quality codebase and have to deal with uncertain return values. Wrapping the return value in the collect() helper will ensure that you always get an iterable to loop over.

// The safe collect() helper.

$items = collect(

// The unsafe method.

$foo->getItems()

);

// Looping over $items will always work.

foreach ($items as $item) {

//

}

Of course, since you’re using Laravel’s collections, you could refactor to their built-in methods:

$items = collect(

$foo->getItems()

);

$items->each(function ($item) {

//

});

Понравилась статья? Поделить с друзьями:
  • Internet explorer ошибка сертификата безопасности что делать
  • Internet explorer ошибка при печати
  • Internet explorer ошибка при запросе
  • Internet explorer ошибка отказано в доступе
  • Inventor ошибка при чтении потока rse inventor