タグアーカイブ PHPエラー

特定商品ブロックを設置した固定ページでfatal errorが発生する問題の直し方

特定商品ブロックを固定ページに配置したときに「Uncaught Error Call to a member function get_id() on null」というfatal errorが表示されるのは、PreCart for WooCommerce のバグが原因だ。プラグインを最新バージョンへ更新するか、functions.php へ一時的な修正コードを追加すれば直る。

なぜ固定ページ上の商品ブロックで fatal error が起こるのか

なぜ固定ページ上の商品ブロックで fatal error が起こるのか

PreCart は WooCommerce の商品情報を扱うフィルターフック(woocommerce_product_add_to_cart_text など)にコールバック関数を登録し、その中で global $product から商品オブジェクトを取得して $product->get_id() を呼び出している。しかし、ブロックエディタで「特定商品」ブロックを通常の固定ページに配置すると、WooCommerce のブロック表示パイプラインではグローバル変数 $product が null のままフィルターが走るケースがある。PreCart のコードには null チェックがないため、null に対して get_id() を呼び出してしまい、致命的なエラーでページ全体が落ちる。

STEP 1 固定ページに「特定商品」ブロックを追加し任意の商品を選択
STEP 2 WooCommerce ブロック描画時に PreCart のフィルターが発火
STEP 3 グローバル変数 $product が null のままコールバックが実行される
STEP 4 $product->get_id() で致命的エラー発生(画面が真っ白になる)

影響を受けるメソッドは change_add_to_cart_text()display_pre_order_messgae()display_pre_order_badge() など、いずれも保護コードがない。WooCommerce の商品ブロックを店舗ページ以外で使っているサイトはすべてこの問題に遭遇し得る。

PreCart を更新してエラーを解消する手順

PreCart を更新してエラーを解消する手順

開発元はこの問題を認識しており、すでに修正アップデートがリリースされている。まずは管理画面からプラグインを最新版に上げるのが最も安全で確実な対処法だ。

STEP 1 WordPress 管理画面へログインし「プラグイン」→「インストール済みプラグイン」を開く
STEP 2 PreCart for WooCommerce に更新通知が出ていたら「今すぐ更新」をクリック
STEP 3 サイトのキャッシュ(プラグインキャッシュ、サーバーキャッシュ)をすべて削除
STEP 4 問題のあった固定ページをフロントエンドで再度開き、エラーが出ないことを確認

更新通知が表示されない場合

「ダッシュボード」→「更新」から更新の再確認を行うか、PreCart のプラグインページで一度「プラグインを削除」→ 公式リポジトリから再インストールする方法もある。ただしこの場合、設定がリセットされる可能性があるため、事前に PreCart の設定をメモしておくかエクスポート機能があれば使っておくと安心だ。

functions.php で null チェックを追加して一時的に対処する方法

functions.php で null チェックを追加して一時的に対処する方法

どうしてもすぐにプラグインを更新できない場合や、何らかの理由で更新後に問題が残る場合は、テーマの functions.php にフックを追加して一時的にエラーを回避できる。

/**
 * PreCart の null チェック不足による fatal error を回避(一時的対応)
 */
add_filter( 'woocommerce_product_add_to_cart_text', function( $text, $product ) {
    if ( ! $product || ! is_a( $product, 'WC_Product' ) ) {
        return $text;
    }
    // 以下は原本の処理が走るが、早期リターンで保護
    return $text;
}, 1, 2 );

add_filter( 'woocommerce_single_product_summary', function() {
    global $product;
    if ( ! $product || ! is_a( $product, 'WC_Product' ) ) {
        return;
    }
    // 同様に早期リターン
}, 1 );

上記のコードは PreCart が使っているのと同じフックに、より優先度の高いコールバック(優先度 1)で null チェックを追加し、商品オブジェクトが存在しないときは処理を打ち切る仕組みだ。PreCart のフィルターよりも先に実行されるため、致命的エラーに至る前に関数を抜けられる。

Before(危険)
global $product;
$product->get_id();
null チェックがないためエラー
After(安全)
if ( ! $product || ! is_a( $product, ‘WC_Product’ ) ) { return; }
$product->get_id();
null のときは早期リターン
修正前  修正後

functions.php 編集時の注意点

子テーマを使っていない場合、テーマ更新で修正が上書きされるリスクがある。必ず子テーマの functions.php にコードを追加するか、Code Snippets プラグインでコードを管理するのが望ましい。また、この一時対応はあくまで応急処置であり、PreCart の他の機能が正常に動作しない可能性もゼロではない。早めに公式アップデートを適用して、追加コードは削除する。

手動修正後に確認しておきたいポイント

手動修正後に確認しておきたいポイント
  • 一時的なコードを追加した後、サイトの表示速度やエラーログに変化がないか定期的にチェックする
  • PreCart の機能(カート追加テキストの変更や予約注文バッジなど)が期待どおり動作しているかテストする
  • PHP のエラーログを確認し、別の箇所で同様の null 参照エラーが隠れていないか調べる
  • サイト全体のキャッシュをクリアし、CDN を利用している場合は CDN キャッシュも破棄する
  • PreCart の更新が確認できたら必ずプラグインを最新版に上げ、追加コードを削除する

よくある質問

PreCart 以外のプラグインでも同じように商品ブロックでエラーが出ることはありますか

ある。WooCommerce のブロックを通常ページで使うと、$product グローバルを正しく取り扱っていない他の拡張プラグインでも同様の null 参照エラーが起きるケースが報告されている。エラーの文面に別のプラグイン名が含まれている場合は、そちらの開発元へ報告しつつ、同じように functions.php で早期リターンを追加すれば応急回避できることが多い。

WooCommerce の商品ブロックを固定ページで使うこと自体は問題ないのでしょうか

WooCommerce のブロックは基本的に店舗ページや商品ページで使うことを想定しているが、WordPress の標準ブロックとして技術的にはどの投稿タイプでも利用できる。プラグインがグローバル変数の有無を適切にハンドリングしていれば固定ページで使っても問題は起きない。ただ、テーマやプラグインが認めるまで、動作確認は入念に行ったほうがよい。

エラーメッセージが表示されずに画面が真っ白になる場合はどうすればよいですか

WordPress が致命的エラーを表示しない設定(WP_DEBUG が false)のときは、管理画面のメールに送られる復旧モード用のリンクを探すか、サーバーの PHP エラーログを確認する。wp-config.php で define('WP_DEBUG', true); を一時的に有効にすれば、画面上にエラー詳細が表示され、原因を特定しやすくなる。なお、本番環境ではデバッグモードをすぐに無効に戻すこと。

管理画面にも入れなくなってしまった場合はどうすれば直りますか

FTP またはレンタルサーバーのファイルマネージャーで /wp-content/plugins/precart/ ディレクトリの名前を一時的に変更(例:precart_deactivated)すれば、プラグインが無効化されて管理画面に再ログインできる。その後、前述の更新や一時コードで対処し、ディレクトリ名を元に戻す。

この記事のポイント

  • 固定ページに WooCommerce 商品ブロックを配置したときの fatal error は PreCart の null チェック不足が原因
  • 解決策は PreCart プラグインの最新版への更新が最も安全で確実
  • すぐに更新できない場合は、functions.php にフックで早期リターンを追加すれば応急回避できる
  • functions.php 編集は子テーマで行い、アップデート後は必ず追加コードを削除する
  • 管理画面に入れなくなったら FTP でプラグインフォルダ名を変更し無効化する