PHP: Fix for “Invalid argument supplied for foreach()”

At some point or another, every PHP developer will come across the following error.

“Warning: Invalid argument supplied for foreach() on line [LINE NUMBER]”

The error will happen if your foreach statement attempts to loop over a variable that is not an array.

More often than not, the cause is a failed SQL query or a function that returns FALSE when there are no results.

It can also happen in cases where your code only creates the array if a certain IF statement is TRUE.

For example, let’s say that we have a function called get_user_posts.

The purpose of this function is to return an array of user comments. However, if no comments exist, then the function will return a boolean FALSE value.

//Get user's posts.
$posts = get_user_posts($userId);

//Loop through the $posts array.
foreach($posts as $userPost){
    //Do something.
}

In the code snippet above, our code wrongly assumes that the $posts variable will always be an array.

If the get_user_posts function returns a boolean FALSE value, then our foreach loop will not work and PHP will dump out the following error message.

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

Not good!

How do I fix this this warning?

The fix will depend on what your code is doing before the foreach loop.

In other words, if the get_user_posts function should return an array at all times, then obviously you will need to investigate why it is returning a FALSE or NULL value instead.

The cause could be any number of things.

  1. You are not declaring a “default” empty array.
  2. Your code does not create the array unless a certain IF statement is TRUE.
  3. One of your database queries is failing.
  4. Your code is overwriting or “unsetting” the array before the loop.

In the past, I have come across APIs and functions that return a FALSE value when there are no results. If this is the case, then you can add the following “check” to your code:

//Get user's posts.
$posts = get_user_posts($userId);

//Loop through the $posts array IF it is an array.
if(is_array($posts)){
    foreach($posts as $userPost){
        //Do something.
    }
}

In the example above, we use the is_array function to check if the $posts variable is an array. We carry out this check before we attempt to loop through it using foreach.

Did you create your array inside an IF statement?

You also need to be careful about creating arrays inside of IF statements.

Take the following example:

if($myVariable == 'search'){
    $myArray = array();
    //code that populates the array goes here
}

foreach($myArray as $v){
    echo $v;
}

In the PHP code above, you can see that we are creating an array if $myVariable is equal to “search”.

We then attempt to loop over it.

However, if $myVariable is not equal to “search”, then the code inside the IF statement will not execute.

As a result, the script will not create the array and the foreach loop will throw an “invalid argument” warning.

To fix this issue, we will need to move the initial array declaration outside of the IF statement. This will ensure that it always exists, even if it does remain empty.

$myArray = array();

if($myVariable == 'search'){   
    //code that populates the array goes here
}

foreach($myArray as $v){
    echo $v;
}

The fix for this “invalid argument” warning will depend on your code.

As we said above, the fix for this error will usually depend on what your code is doing before the loop takes place.

In some cases, it can be something as simple as an SQL error. In other cases, it can be a design flaw.

To debug this issue, you will need to go back and figure out where you are creating the array.

It is also important to note that blindly adding the is_array check when the variable in question should be an array is not wise.

This is because you will be covering up a bug that shouldn’t exist in the first place.