WordPressをPHP 8.0以上の環境にアップデートした際、Trying to access array offset on false in… というエラーが表示されることがあります。
当記事では、エラーが発生する原因と解決例を解説します。
エラーの概要
原因としては配列ではない変数に対して、配列のキーを指定して値を取り出そうとしたことです。
配列が返ってくるはずの処理で、 false(または null)が返ってきてしまい、そこに対して $data['key'] のようなアクセスを行ったときに発生します。
本来であれば配列データが返るはずの処理において処理が失敗し、戻り値が false (処理失敗を示す値)または null (値が空)になることがあります。
その状態の変数に対し $data['key'] のような配列アクセスを実行すると、この警告が発生します。
このエラー自体は致命的なエラーではなく警告であるため、サイトの表示が完全に止まることは少ないですが、放置すると以下のようなリスクがあります。
- 画面上に不要な警告文が表示され、サイトの見た目や信頼性、セキュリティが損なわれる
- 本来表示されるべきデータが表示されずレイアウトが崩れる
- 将来的なPHPバージョンアップで致命的エラーに格上げされる可能性がある
エラーが起こる例
実際にWordPressの functions.php でよく見られる例を紹介します。
以下は、固定ページの wpautop(段落の自動整形)を無効化するために書かれたコードです。
add_filter('the_content', 'wpautop_filter', 9);
function wpautop_filter($content) {
global $post;
$remove_filter = false;
$arr_types = array('page'); //適用させる投稿タイプを指定
$post_type = get_post_type( $post->ID );
if (in_array($post_type, $arr_types)) $remove_filter = true;
if ( $remove_filter ) {
remove_filter('the_content', 'wpautop');
remove_filter('the_excerpt', 'wpautop');
}
return $content;
}一見、特に配列を扱っているようには見えないコードですが、このコードは特定の条件下で Trying to access array offset on false を発生させます。
原因は global $post; の直後にある $post->ID です。
$post_type = get_post_type( $post->ID );WordPressの the_content フィルターが呼び出されるタイミング、表示しているアーカイブページや特定のカスタムページなどによっては、投稿情報を保持するグローバル変数 $post が、オブジェクトではなく null や false になっている場合があります。
この状態で $post->ID のような記述を実行すると、WordPressの内部関数であるget_post_type() などが投稿IDを正しく解決できません。
その結果、関数内の内部処理で false になったデータに対して配列アクセスが行われ、この警告が発生します。
エラーが起こる原因
このエラーが発生する主な原因は、以下の3つに分類されます。
1. 想定していたデータが存在しない
カスタムフィールドの値が未入力だったり、取得しようとしたデータがそもそも存在しなかったりすると関数が配列の代わりに false を返します。
特に投稿ごとに入力が任意のカスタムフィールドで起こりやすくなります。
2. 関数やAPIがエラー・失敗を返している
json_decode() は不正なJSON文字列を渡されると null を返し、DB検索系の関数やAPIリクエストも、接続失敗やデータ不整合時に false を返す設計になっているものが多くあります。
この戻り値を確認せずに、常に配列を返す前提でコードを書いていると発生します。
3. PHPのバージョンアップによる仕様変更
PHP 7.4以前では、配列でない値へのアクセスは警告こそ出ても比較的静かに処理されていました。
しかしPHP 8.0以降厳格化が進み、これまで表面化していなかった潜在的な不具合が可視化されるようになりました。
サーバーのPHPバージョンをアップグレードした直後に急にこのエラーが出始めたというケースもよく見られます。
エラーの解決方法
解決するには配列へアクセスをする前に、その変数が本当に配列かつ目的のキーが存在するかを確認する記述を追加します。
解決例
前述のコードの原因は $post が WP_Post オブジェクトになっていない状態で $post->ID にアクセスしていたことでした。
そこで、$post が正しい投稿オブジェクトであることを instanceof WP_Post で確認してから処理を行うよう修正します。
add_filter('the_content', 'wpautop_filter', 9);
function wpautop_filter($content) {
global $post;
$remove_filter = false;
$arr_types = array('page'); //適用させる投稿タイプを指定
// $post が正しい投稿オブジェクトの場合のみ処理する
if ( $post instanceof WP_Post ) {
$post_type = get_post_type( $post->ID );
if ( in_array( $post_type, $arr_types, true ) ) {
$remove_filter = true;
}
}
if ( $remove_filter ) {
remove_filter('the_content', 'wpautop');
remove_filter('the_excerpt', 'wpautop');
}
return $content;
}ポイントは以下の2点です。
$post instanceof WP_Postで、$postが確実に投稿オブジェクトであることを確認してから、$post->IDにアクセスしているin_array()の第3引数にtrueを渡し、厳密な型比較(===)にすることで意図しない一致を防いでいる
※必須ではありませんがより安全になります。
この修正により、$post が未設定のタイミングで the_content フィルターが呼ばれても、警告を出すことなく安全にスルーされるようになります。
その他の解決方法
テーマ・プラグインを最新版に更新する
自分で書いたコードではなく、使用中のテーマやプラグインの中でこのエラーが出ている場合は、開発元が既にPHP 8.0以降対応の修正版をリリースしている可能性があります。
該当のテーマ・プラグインを最新版にアップデートすることで解消されるケースも多いため、まずは更新の有無を確認しましょう。
まとめ
PHP 8.0以降にアップデートすると起こりやすいエラーなので、
変数が本当に配列かつキーが存在するかを確認する記述を追加しておきましょう。

