TL;DR
PHP 7.2 tightened up count() โ it now throws a warning when you pass null or anything that isn't an array or Countable. Guard with a null check before counting:
// Before (breaks in PHP 7.2+)
$total = count($items);
// After โ safe version
$total = is_array($items) || $items instanceof Countable ? count($items) : 0;
// Or the one-liner most people reach for
$total = count($items ?? []);
What Triggers This Warning
In PHP 7.1 and earlier, count(null) silently returned 0. count('hello') returned 1. No fuss, no warning โ which also meant bugs went unnoticed for years.
PHP 7.2 changed the rules. Now count() only accepts arrays or objects that implement Countable. Pass it null, an integer, a string, or a boolean and you get:
PHP Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/html/index.php on line 42
The classic trigger: a database query returns null when there are no results, and your code calls count() on it without checking first.
Step 1 โ Find the Offending Variable
The warning tells you exactly where to look โ file and line number. Open that file, find the count() call, and add a var_dump() just above it:
var_dump($items); // What does $items actually contain?
$total = count($items);
See NULL in the output? That's your culprit. Here's where null usually sneaks in:
- A PDO/MySQLi query with no results โ some drivers return
nullinstead of[] - A function that hits a return path without an explicit return value (PHP returns
nullimplicitly) json_decode()failing on malformed JSON โ returnsnullsilently- An uninitialized variable
- A missing config or session value
Fix Approaches
Option 1 โ Null coalescing (cleanest for PHP 7.0+)
$total = count($items ?? []);
When $items is null, the ?? operator substitutes an empty array. count([]) returns 0. Done. This covers 90% of real-world cases and reads clearly at a glance.
Option 2 โ Explicit type check
if (is_array($items) || $items instanceof Countable) {
$total = count($items);
} else {
$total = 0;
}
More verbose, but useful when you need to handle the non-array case differently โ say, logging a warning or throwing an exception instead of defaulting to 0.
Option 3 โ Cast to array
$total = count((array) $items);
Works, but watch the edge cases: (array) null โ [] (count 0), but (array) 'hello' โ ['hello'] (count 1). Only reach for this when you're certain the value is either an array or null โ nothing else.
Option 4 โ Fix the source function
Sometimes the right fix isn't at the count() call โ it's upstream. Make the function that returns the data always return an array:
// Fragile: might return null if the query fails
function getUsers(PDO $pdo): ?array {
$stmt = $pdo->query('SELECT * FROM users');
return $stmt->fetchAll();
}
// Solid: always returns an array, caller never has to guess
function getUsers(PDO $pdo): array {
$stmt = $pdo->query('SELECT * FROM users');
return $stmt ? $stmt->fetchAll(PDO::FETCH_ASSOC) : [];
}
WordPress / Plugin-specific fix
Seeing this after upgrading a WordPress site to PHP 7.2+? The plugin hasn't been updated. Patch it locally:
// Original plugin code (broken on PHP 7.2+)
$count = count($some_option);
// Patched
$count = is_array($some_option) ? count($some_option) : 0;
That buys you time, but the real fix is opening a bug report with the plugin author and switching to a maintained version.
Silencing vs Fixing
Some Stack Overflow answers suggest @count($items) to suppress the warning. Skip it. Suppressing the error means you'll never know when $items is null and it shouldn't be. Warnings exist for a reason โ they're PHP telling you something unexpected is happening. Fix the cause, not the symptom.
Verifying the Fix
Apply your fix, then watch the log to confirm the warning is gone:
# Tail your PHP error log
tail -f /var/log/php/error.log
# Or check the web server error log
tail -f /var/log/nginx/error.log
# Temporarily crank up error reporting to catch anything else
error_reporting(E_ALL);
ini_set('display_errors', '1');
Trigger the code path that was failing. No warning in the log? You're done.
For a quick terminal sanity check:
php -r "echo count(null);" # PHP 7.1: prints 0 silently
# PHP 7.2+: Warning + prints 0
php -r "echo count(null ?? []);" # PHP 7.2+: prints 0, no warning
If You're on a Legacy Codebase
Jumping from PHP 7.1 to 7.2+ on a large app? Expect dozens of these warnings to surface at once. Fixing every call site immediately isn't realistic. A helper function lets you migrate in bulk:
/**
* Drop-in replacement for count() that doesn't warn on null.
*/
function safe_count($value): int {
if (is_array($value) || $value instanceof Countable) {
return count($value);
}
return 0;
}
Do a project-wide search for count( and replace with safe_count( where appropriate. It's not pretty long-term, but it unblocks the PHP upgrade without a week of call-site archaeology.

