PHP 7.2 の WordPress で Warning: count(): … のエラーが出る

  • WordPress

PHP を 7.2 にアップデートしたところ、WordPress で下記の Warning が出るようになりました。

Warning: count(): Parameter must be an array or an object that implements Countable in … /wp-includes/post-template.php

/wp-includes/post-template.phpはコアファイルですが、WordPress 5.1.1 ( 2019/4/27 時点の最新版 ) は PHP 7.2 に対応しているため、テーマファイルもしくはプラグインから波及したエラーだと考えられます。

原因

追ってみるとエラーになっているのは下記です。

/wp-includes/post-template.php

...

if ( $page > count( $pages ) ) { // if the requested page doesn't exist
    $page = count( $pages ); // give them the highest numbered page that DOES exist 
}

...

エラーの内容は「count()は配列かオブジェクトを渡さないとだめだよ」というものだったので確認してみると、エラーの出ていたページでは$pagesというグローバル変数にNULLが入っていました。確かにNULLは数えられません。

ちなみにcount()は PHP7.2 から仕様が変更になったため、カウントできないものを入れると Warning が発生するようになったようです。

テーマテンプレートの修正

WordPress コアファイル(wp-admin/、wp-includes/ などにあるファイル)やプラグインフォルダ内でエラーが出ているからと言って、その箇所を修正するのは基本的にタブーです。

たまにコアファイルを直接編集している人をみかけますが、WordPress 自体をアップデートした時に再度同じ修正をする必要になるため絶対にやってはいけません。

今回の場合、おそらく記事の詳細ページ・固定ページで起きているエラーだと思います。そのため、single.php もしくは page.php を修正します(もし他のテンプレートで同様のエラーが起きている場合、下記を参考にしながら記事ループの箇所を確認してください)。

グローバル変数$pagesに変数がセットされていない事がそもそもの原因なので、対象ファイルの一番最初の行に下記を追加しました。

<?php the_post(); ?>

たったこれだけですが、これで$pagesに空の配列がセットされるようになりエラーが解消されました。

詳細までは追えていませんが、どうやらthe_post()によってsetup_postdata( $post )が呼ばれ、この中で$pagesに初めて値がセットされるようです。ちなみに、$pages<!--next page-->でページ分割したコンテンツがセットされる配列です。

本来は single / page でもループを使ったほうが良い

single.php や page.php は1記事しかデータを呼び出さないので直接the_title()等のループ関数を使ってしまいがちですが、本来は下記のループの中に記事出力をすることが推奨されています。

<?php if ( have_posts() ): while( have_posts() ): the_post(); ?>
    ... 記事は1つなので1ループしかしない ...
<?php endwhile; endif; ?>

ループを使う意味はまだよくわかっていないのですが、内部的に必要な処理を行っているかもしれないので従っておいた方がよさそうですね。