TL;DR
PHP 7.2 で count() の仕様が厳格化されました — null や配列・Countable 以外の値を渡すと警告が発生します。カウント前に null チェックで対処しましょう:
// 以前(PHP 7.2+ では動作しない)
$total = count($items);
// 以降 — 安全なバージョン
$total = is_array($items) || $items instanceof Countable ? count($items) : 0;
// あるいはよく使われるワンライナー
$total = count($items ?? []);
この警告が発生する原因
PHP 7.1 以前では、count(null) は警告なしに 0 を返していました。count('hello') は 1 を返していました。何も問題なく — その代わり、バグが何年も気づかれないまま放置されていました。
PHP 7.2 でルールが変わりました。現在 count() は配列または Countable を実装したオブジェクトのみを受け付けます。null、整数、文字列、真偽値を渡すと以下のエラーが発生します:
PHP Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/html/index.php on line 42
典型的なケース:データベースクエリが結果なしで null を返したとき、コードが事前チェックなしに count() を呼び出してしまうパターンです。
ステップ 1 — 問題の変数を特定する
警告にはファイルと行番号が正確に示されています。該当ファイルを開き、count() の呼び出し箇所を見つけて、その直上に var_dump() を追加します:
var_dump($items); // $items には実際に何が入っているか?
$total = count($items);
出力に NULL が表示されていれば、それが原因です。null が紛れ込む典型的なケースは次のとおりです:
- 結果なしの PDO/MySQLi クエリ — ドライバによっては
[]ではなくnullを返す - 明示的な戻り値なしの return パスを通る関数(PHP は暗黙的に
nullを返す) - 不正な JSON に対して
json_decode()が失敗 — 警告なしにnullを返す - 初期化されていない変数
- config やセッション値の欠落
修正方法
方法 1 — Null 合体演算子(PHP 7.0+ で最もシンプル)
$total = count($items ?? []);
$items が null のとき、?? 演算子が空の配列に置き換えます。count([]) は 0 を返します。これで完了です。実際のケースの 90% をカバーし、一目でわかりやすいコードになります。
方法 2 — 明示的な型チェック
if (is_array($items) || $items instanceof Countable) {
$total = count($items);
} else {
$total = 0;
}
冗長ですが、配列でないケースを別途処理したい場合 — 例えば 0 をデフォルトにする代わりに警告をログに記録したり例外を投げたりする場合に便利です。
方法 3 — 配列にキャスト
$total = count((array) $items);
動作しますが、エッジケースに注意してください:(array) null → [](count 0)ですが、(array) 'hello' → ['hello'](count 1)になります。値が配列または null のいずれかであることが確実な場合のみ使用してください — それ以外は避けましょう。
方法 4 — ソース関数を修正する
修正箇所が count() の呼び出し側ではなく、上流にある場合もあります。データを返す関数が常に配列を返すようにしましょう:
// 脆弱:クエリが失敗すると null を返す可能性がある
function getUsers(PDO $pdo): ?array {
$stmt = $pdo->query('SELECT * FROM users');
return $stmt->fetchAll();
}
// 堅牢:常に配列を返し、呼び出し側が推測する必要がない
function getUsers(PDO $pdo): array {
$stmt = $pdo->query('SELECT * FROM users');
return $stmt ? $stmt->fetchAll(PDO::FETCH_ASSOC) : [];
}
WordPress / プラグイン固有の修正
WordPress サイトを PHP 7.2+ にアップグレードした後にこのエラーが出ていますか?プラグインが更新されていないのが原因です。ローカルでパッチを当てましょう:
// 元のプラグインコード(PHP 7.2+ では動作しない)
$count = count($some_option);
// パッチ済み
$count = is_array($some_option) ? count($some_option) : 0;
これは一時しのぎですが、根本的な解決策はプラグイン作者にバグレポートを送り、メンテナンスされているバージョンに移行することです。
警告の抑制 vs 修正
Stack Overflow の一部の回答では @count($items) で警告を抑制することを提案しています。これは避けてください。エラーを抑制すると、$items が null であるべきでないときに null になっていることに気づけなくなります。警告には存在する理由があります — PHP が予期しない状態が発生していることを伝えているのです。症状ではなく原因を修正しましょう。
修正の確認
修正を適用したら、ログを監視して警告が消えたことを確認します:
# PHP エラーログをリアルタイム確認
tail -f /var/log/php/error.log
# または Web サーバーのエラーログを確認
tail -f /var/log/nginx/error.log
# 他の問題も捕捉するためエラーレポートを一時的に最大化
error_reporting(E_ALL);
ini_set('display_errors', '1');
問題が発生していたコードパスを実行してください。ログに警告が出なければ完了です。
ターミナルで素早く確認する場合:
php -r "echo count(null);" # PHP 7.1: 警告なしに 0 を出力
# PHP 7.2+: 警告 + 0 を出力
php -r "echo count(null ?? []);" # PHP 7.2+: 0 を出力、警告なし
レガシーコードベースの場合
大規模なアプリを PHP 7.1 から 7.2+ に移行する場合、一度に大量の警告が表示されることが予想されます。すべての呼び出し箇所を即座に修正するのは現実的ではありません。ヘルパー関数を使えば一括移行が可能です:
/**
* null で警告が出ない count() のドロップイン代替関数。
*/
function safe_count($value): int {
if (is_array($value) || $value instanceof Countable) {
return count($value);
}
return 0;
}
プロジェクト全体で count( を検索し、適切な箇所を safe_count( に置き換えてください。長期的にはきれいな解決策ではありませんが、何週間もかけて呼び出し箇所を調査することなく PHP のアップグレードを進められます。

