【WordPressエラー】「Warning: Undefined variable $post in …」「Warning: Attempt to read property “ID” on null in …」

目次

WordPressがPHPの更新を求めてくる理由

WordPress管理画面に「PHPの更新が必要です」という赤いアラートが表示されることがあります。これはサイトで使用しているPHPのバージョンが古く、セキュリティサポートが終了している、またはまもなく終了することを意味しています。

2026年5月現在、WordPress公式が推奨しているPHPバージョンは 8.3以上 です。各バージョンのセキュリティサポート期限は以下のとおりです。

PHPバージョンセキュリティサポート期限
8.12025年12月31日
8.22026年12月31日
8.32027年12月31日
8.42028年12月31日

PHP 7.4以下はすでにサポートが完全に終了しています。サーバー管理画面でPHPバージョンを確認し、7系を使っている場合は早めに8系への移行を検討してください。

ただし、PHPのメジャーバージョンを上げると、これまで動いていたコードがエラーを出すことがあります。

PHP7からPHP8で変わったエラーの扱い

PHP7以前では、未定義の変数にアクセスした場合のエラーレベルは E_NOTICE(通知)でした。多くのサーバー環境ではデフォルトで E_NOTICE は非表示に設定されていたため、コードに問題があっても気づかないまま動作していたケースが多くあります。

PHP8.0ではここに2つの変更が入りました。

  • 未定義変数へのアクセスが E_NOTICE から E_WARNING(警告)に昇格した
  • デフォルトの error_reportingE_ALL に変更された

この2つが組み合わさることで、PHP7では表示されなかったエラーがPHP8では画面上に表示されるようになりました。さらにPHP9.0では、未定義変数へのアクセスはErrorException(致命的エラー)に昇格する予定がアナウンスされています。つまり、今のうちに対処しておかないと、将来的にはサイトが完全に停止するリスクがあります。

(提案内容)未定義変数へのアクセスを E_WARNING から Error exception に昇格させる
https://wiki.php.net/rfc/undefined_variable_error_promotion

未定義変数アクセス時のエラーレベルの変遷 PHP 7.x E_NOTICE(通知) デフォルトで非表示 → 気づかず動作 PHP 8.x E_WARNING(警告) E_ALL がデフォルト → 画面に表示される PHP 9.0(予定) Error(致命的) 実行が停止する → サイト表示不可 PHP8で表示されるようになった理由 1. エラーレベルが E_NOTICE → E_WARNING に昇格 2. error_reporting のデフォルトが E_ALL に変更 → 今まで隠れていた問題が一気に表面化する

「get_the_terms」記事に基づくタクソノミーの取得のための下記の記述でエラー発生

<?php
$terms = get_the_terms($post->ID, 'tag-workshop');
if ($terms) {
    foreach ($terms as $term) {
        echo '<a class="tagc-tag-workshop" tag-id="' . $term->term_id . '" href="' . get_permalink() . '">' . $term->name . '</a>';
    }
}
?>

Warning: Undefined variable $post in …

Warning: Attempt to read property “ID” on null in …

1つ目の Undefined variable $post は、変数 $post がそのスコープ内で定義されていないことを示しています。2つ目の Attempt to read property "ID" on null は、$post が null であるにもかかわらず、そのプロパティ ID を読み取ろうとしたことによるエラーです。この2つはセットで発生します。

なぜ $post が未定義になるのか

WordPressには $post というグローバル変数があり、現在表示中の投稿オブジェクトが格納されています。メインのテンプレートファイル(single.php、page.phpなど)のトップレベルでは、WordPressのテンプレートローダーがこの変数をセットアップしてくれるため、明示的な宣言なしでも $post を使えます。

しかし、以下のような状況では $post はスコープ内に存在しません。

  • テンプレートパーツ内(get_template_part() で読み込まれたファイル)
  • 関数の内部
  • ウィジェットやショートコードのコールバック内
  • functions.php 内の処理

PHPでは関数の内部からグローバル変数に直接アクセスすることはできません。これはPHPの変数スコープの仕様です。PHP7でもこの問題は存在していましたが、先述のとおり E_NOTICE は多くの環境で非表示だったため、$post が null のまま処理が進み、結果的に動いているように見えていただけです。

PHPの変数スコープと $post の関係 グローバルスコープ $post = WP_Post オブジェクト(WordPressが自動セット) 関数スコープ(ローカル) function my_func() { // $post は未定義 // → Undefined variable } 修正後 function my_func() { global $post; // グローバルの $post を // 参照できるようになる } global宣言で参照可能 アクセス不可 アクセス可

解決策:global $post; を宣言する

対処はシンプルです。$post を使用する前に global $post; を宣言し、グローバルスコープの変数をローカルスコープに引き込みます。

修正前のコード:

php

<?php
$terms = get_the_terms($post->ID, 'tag-workshop');
if ($terms) {
    foreach ($terms as $term) {
        echo '<a class="tagc-tag-workshop" tag-id="' . $term->term_id . '" href="' . get_permalink() . '">' . $term->name . '</a>';
    }
}
?>

修正後のコード:

php

<?php
global $post;
$terms = get_the_terms($post->ID, 'tag-workshop');
if ($terms) {
    foreach ($terms as $term) {
        echo '<a class="tagc-tag-workshop" tag-id="' . $term->term_id . '" href="' . get_permalink() . '">' . $term->name . '</a>';
    }
}
?>

先頭に global $post; を1行追加するだけで、Undefined variable $postAttempt to read property "ID" on null の両方が解消します。

global $post; 以外の書き方

global $post; は最もシンプルな解決策ですが、WordPress開発においてはほかの方法も知っておくと応用が利きます。

get_post() 関数を使う

get_post() は引数なしで呼ぶと、現在のグローバル $post と同等のオブジェクトを返します。グローバル変数を直接触らないため、副作用のリスクが低い書き方です。

php

<?php
$current_post = get_post();
if ($current_post) {
    $terms = get_the_terms($current_post->ID, 'tag-workshop');
    if ($terms) {
        foreach ($terms as $term) {
            echo '<a class="tagc-tag-workshop" tag-id="' . $term->term_id . '" href="' . get_permalink() . '">' . $term->name . '</a>';
        }
    }
}
?>

get_post() の戻り値が null の可能性もあるため、if ($current_post) でチェックを入れておくとより安全です。

get_queried_object_id() を使う

アーカイブページやタクソノミーページなど、投稿以外のページでも使える方法です。ただし、使えるのはメインクエリのコンテキストに限られます。

<?php
$post_id = get_queried_object_id();
if ($post_id) {
    $terms = get_the_terms($post_id, 'tag-workshop');
    if ($terms) {
        foreach ($terms as $term) {
            echo '<a class="tagc-tag-workshop" tag-id="' . $term->term_id . '" href="' . get_permalink() . '">' . $term->name . '</a>';
        }
    }
}
?>

使い分けの目安

方法適した場面注意点
global $post;テンプレートパーツでの簡易的な利用グローバル変数を直接参照するため、カスタムクエリ内で $post が上書きされている場合は意図しない値になることがある
get_post()関数内での利用、プラグイン開発戻り値の null チェックが必要
get_queried_object_id()メインクエリのIDだけが欲しい場合サブクエリ(WP_Query)のループ内では使えない

PHP8移行時にチェックすべきポイント

$post の問題はPHP8移行で発生するエラーの一例にすぎません。同様のパターンで、ほかの箇所でも Undefined variable が噴出する可能性があります。移行作業を進める前に、以下のポイントを確認してください。

本番環境を直接更新しない

レンタルサーバーのPHPバージョン切り替えは、多くの場合ワンクリックで完了します。しかし、切り替えた瞬間にサイトが真っ白になる可能性があります。ステージング環境やローカル環境で事前にテストしてください。

テーマ・プラグインの対応状況を確認する

特に古いテーマや長期間更新されていないプラグインは、PHP8に対応していないことがあります。管理画面で更新可能なプラグインがあれば、PHPバージョンを上げる前にすべて最新にしておくのが基本です。

WP_DEBUG で隠れたエラーを洗い出す

wp-config.php に以下を設定すると、画面には表示せずログファイルにエラーを記録できます。

php

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

ログは wp-content/debug.log に出力されます。PHP8に切り替えた後、サイトの主要ページを一通り巡回して、このログに出ているWarningを潰していく作業が現実的な進め方です。

バックアップを取る

PHPバージョンの変更前には、ファイルとデータベースの両方をバックアップしてください。万が一問題が発生した場合に、元のPHPバージョンに戻すだけでなく、ファイルも復元できる状態にしておくことが重要です。

今後のアクション

PHP8.x系での Undefined variable は Warning(警告)なので、現時点ではサイトが完全に停止することはありません。しかし、PHP9.0ではこれが致命的エラーに昇格する予定です。Warning が出ている箇所は「今は動いているが将来壊れるコード」と捉えて、見つけたタイミングで対処しておくのが得策です。

手始めに WP_DEBUG を有効化してログを確認し、Undefined variable が出ている箇所をリストアップするところから始めてみてください。多くの場合、global 宣言の追加や get_post() への置き換えといったシンプルな修正で解決します。

参考リンク


【PHP7から8へ切替】Warning: Undefined variableが表示された場合の修正方法
https://it-column.mjeinc.co.jp/archives/3513

WordPressのグローバル変数「$post」とは?中身や使い方について解説
https://tcd-theme.com/2024/01/wp-post-object.html

PHP8.0でWordPressの「Attempt to read property “ID” on null」のエラーを解決したい
https://ja.stackoverflow.com/questions/85387/php8-0%e3%81%a7wordpress%e3%81%ae-attempt-to-read-property-id-on-null-%e3%81%ae%e3%82%a8%e3%83%a9%e3%83%bc%e3%82%92%e8%a7%a3%e6%b1%ba%e3%81%97%e3%81%9f%e3%81%84

目次