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.

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

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

Hmm. Not good.

“OK, so 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 a 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 no results are present. 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 over it using the foreach construct.

IF statements.

You also need to be wary 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 I am creating an array if $myVariable is equal to “search”. I 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 particular issue, we will need to move the initial array declaration outside of the IF statement. This will ensure that it always exists, even if does remain empty.

The fix depends on the code.

As I 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, as you will be┬ácovering up a bug that shouldn’t exist in┬áthe first place.