Common causes
- Passing null where an array or string is required, often from a failed lookup
- count(), implode() or array_merge() used on a value that is not an array
- Numeric strings from forms or databases passed to int parameters under declare(strict_types=1)
- Old plugins or themes written for PHP 7 now running on PHP 8
- Argument order changed, for example implode() with the array first and glue second (removed in PHP 8)
- A typed property or parameter receiving data from an API in a different format
How to fix it
- Read the three parts of the message. Note the function name, the argument number and name, and the "X given" type. The "called in" path shows where the wrong value came from.
- Trace the bad value. Go to the calling line and find where that variable is set. If it is null, the earlier lookup found nothing; handle that case there.
- Add a safe default. Use count($items ?? []) or (array) casts carefully, or set defaults where the data is loaded, so the function always gets the type it needs.
- Convert input explicitly. Form and database values are strings. Cast them, for example (int) $_POST['qty'], after validating them with filter_var() or is_numeric().
- Update or patch old code. If the error is in a plugin or theme, update it. For your own code, fix PHP 8 changes such as the implode() argument order and count() on non-arrays.
Validate and cast values before passing them
$items = get_post_meta($id, 'items', true) ?: [];
echo count($items);
$qty = filter_var($_POST['qty'] ?? null, FILTER_VALIDATE_INT);
if ($qty === false) {
throw new InvalidArgumentException('Invalid quantity');
}
$cart->add($productId, $qty); How to stop it happening again
- Use type declarations everywhere so errors show up early in development
- Validate and cast all request data at the edge of your app
- Test plugins and themes on PHP 8 staging before upgrading live
- Run PHPStan at a level that checks argument types