Fixing the 'Invalid argument supplied for foreach()' PHP Warning

beginner🐘 PHP2026-06-06| Any PHP environment (Linux, Windows, macOS) running PHP 5.6, 7.x, or 8.x.

Error Message

Warning: Invalid argument supplied for foreach() in /var/www/html/index.php on line 42
#php#foreach#array#warning#debugging

The WarningYou’re checking your error logs and see a wall of warnings. Line 42 is shouting: Warning: Invalid argument supplied for foreach(). It is a classic PHP headache. Usually, it simply means you are trying to loop through a variable that isn't a collection.

Why This HappensThe foreach construct is picky. It strictly requires an array or an object that implements the Traversable interface. If you feed it null, a string, or a boolean, PHP gives up and throws this warning. This often happens when a function you expected to return data fails and returns false instead.

Real-World Scenarios- Empty Database Queries: A PDO::fetch() call returns false because no rows matched your criteria.- Broken API Responses: json_decode() returns null because an external service sent an HTML 404 page instead of valid JSON.- Skipped Logic: A variable is only initialized inside an if statement that never executed.- Uninitialized Variables: You referenced a variable that was never declared as an array.## How to Fix the Error### 1. Use the Null Coalescing Operator (Best for PHP 7+)The ?? operator is the cleanest solution for modern code. It allows you to provide an empty fallback array instantly if the variable is missing or null.

// The safer way:
foreach ($users ?? [] as $user) {
    echo $user['name'];
}

2. Quick Array CastingIf you want to force the variable into an iterable format, cast it. This turns null into an empty array and a single string into an array containing that string.

// Ensures the input is always iterable
foreach ((array)$userData as $item) {
    process($item);
}

Warning: Be careful with booleans. Casting false results in [false], which means your loop will run once with a useless value.

3. Defensive Checks with is_iterable()For complex logic, use is_iterable() (available since PHP 7.1). It is more robust than is_array() because it also accounts for objects that can be looped.

if (is_iterable($products)) {
    foreach ($products as $product) {
        echo $product->title;
    }
} else {
    // Handle the "no data" state gracefully
    echo "No products available.";
}

4. Start with an Empty BucketPrevent errors by initializing your variables at the start of your script. This ensures the loop always has something to look at, even if it is empty.

$results = []; // Initialize early

if ($searchActive) {
    $results = $db->getResults() ?: []; // Fallback to empty if false
}

foreach ($results as $row) {
    // No warning here
}

Debugging the ValueStill not sure why the variable is empty? Use var_dump() or gettype() right before the loop to see exactly what is inside. Often, you will find a null where you expected a list of users.

Verification Steps- Reproduce: Trigger the specific condition (like a failed search) that causes the empty variable.- Check Logs: Run tail -f /var/log/apache2/error.log while you refresh the page.- Validate: Confirm that the warning is gone and the page renders correctly even without data.- Test Edge Cases: Pass an empty string or 0 to ensure your fix handles various "empty" types.## Long-term PreventionIn PHP 7.4 and 8.x, use Strict Type Hinting. By defining return types for your functions, you catch these errors during development. If a function promises an array, make sure it always returns one—even if it's just []. This eliminates the need for defensive checks in your templates.

Related Error Notes