上級者向け

第4回:PHPだけでは解決できない「動かない」の深層。Reactエラーとヘッドレス時代のデバッグ

第4回:PHPだけでは解決できない「動かない」の深層。Reactエラーとヘッドレス時代のデバッグ
WEB先案内

WordPressのトラブル対応は、長らくPHP中心のデバッグで成立してきました 。サーバーのエラーログを確認し、致命的なエラー(Fatal Error)を修正して再アクセスする。しかし、ブロックエディタ以降のWordPressでは、このアプローチだけでは説明できない不具合が確実に増えています

  • 保存ボタンを押しても反応しない 。
  • 「更新に失敗しました」とだけ表示される 。
  • 管理画面だけが壊れて、フロントエンド(公開画面)は正常に表示される 。

PHPのログには何も出ていないのに、操作が成立しない。これは例外ではなく、現在のWordPressの構造上、必然的に起きる問題です 。本稿では、PHPの先にある「実行層」のデバッグ術を詳しく解説します。

目次
  1. WordPressはいつから「PHPのCMS」ではなくなったのか
  2. 「更新に失敗しました」の裏側で起きていること
  3. Minified React Error と SourceMap の活用
  4. jQueryとReactの共存と「思想」の違い
  5. webpack / npm が絡むと「本番だけ壊れる」理由
  6. ヘッドレスWordPressでは問題はどこに移るか
  7. CORSと認証は「別物」だが同時に壊れる
  8. 本番JSトラブル時のチェックリスト
  9. 上級者Q&A:管理画面・ブロックエディタのJSトラブル実践編
  10. まとめ
  11. ウェブナラはじめました!

WordPressはいつから「PHPのCMS」ではなくなったのか

現在のWordPress管理画面、特にブロックエディタ(Gutenberg)は、ブラウザ上のアプリケーションとして動作しています。かつてのようにPHPがHTMLを組み立てて出力するのではなく、現在のWordPress管理画面、特にブロックエディタ(Gutenberg)は、

  • React(UIと状態管理)
  • JavaScript(操作ロジック)
  • REST API(データ通信)

によって構成されたブラウザ上のアプリケーション です。

ここで重要なのは、役割分担です。

役割担当
UI・操作ユーザーのクリックや入力の受付React / JavaScript
通信データのやり取り(中継)REST API
保存処理データベースへの書き込みPHP
表示更新保存結果を画面に反映させるReact

PHPは今や「最後に保存する人」です。
画面が壊れている=PHPの問題とは限らない

この前提を受け入れない限り、
第3回で扱ったINP(体感速度)も、
今回のJSエラーも、理解は分断されたままです。

「更新に失敗しました」の裏側で起きていること

ブロックエディタで保存するとき、内部では次の流れが起きています。

  1. Reactが編集状態を管理
  2. REST APIへJSON形式でデータを送信
  3. PHPが受け取ったデータをDBに保存
  4. JSONで処理結果(成功・失敗)を返却
  5. Reactがその返却データを解釈し、画面を更新

「更新に失敗しました」というメッセージは、

このどこかで契約違反が起きた

という最終結果の表示にすぎません。

REST APIとJSONの定義

ここでの最重要ポイントはこれです。

JSONは1文字でも余計な出力が混じると壊れる

PHP側で以下のような出力が混入すると、PHPの処理自体は成功していても、ReactがJSONを解釈できず「保存失敗」となります

  • echo / var_dump:
    デバッグ用の出力がそのまま残っている 。
  • Notice / Warning:
    致命的ではないが、PHPが出力してしまう警告文 。
  • BOM(バイトオーダーマーク):
    ファイルの先頭に隠れている不可視のコード 。
  • HTMLタグ / 空白:
    意図しない改行やスペース 。
チェックポイント
生(Raw)データ確認方法
生(Raw)データ確認方法

Minified React Error と SourceMap の活用

DevToolsのコンソールで「Minified React error #130」のような番号のエラーが出るのは、Reactが本番用に最適化(Minify)されているためです。

用語解説

Minify(最適化、圧縮):
ファイルサイズ削減と実行速度向上のため、コード内のスペースを詰め、変数名を短くし、エラーメッセージを番号に置き換える処理です 。

ReactとMinifyの関係

Reactは開発環境では、

  • どのコンポーネントで
  • 何が壊れたか

を詳細に表示します。

しかし本番環境では、

  • ファイルサイズ削減
  • 実行速度最適化

のため、
エラーメッセージを番号に置き換えます

エラーメッセージを番号で置き換えている仕組みとは?

この仕組みをSourceMapで実現しています。具体的には、

  • 圧縮後のJS
  • 元の人間可読なJS

を対応付ける 地図ファイル(.map) です。

DevToolsでSourceMapが有効であれば、

  • 実際の関数名
  • 元の行番号
  • 呼び出し元

まで遡れます。

本番と同じ構成をローカルやステージング環境で再現し、開発モードでフルメッセージを確認するのが上級者の手順です。

jQueryとReactの共存と「思想」の違い

WordPressはいまも jQuery を同梱しています。
一方、ブロックエディタは React 前提です。

問題は思想ではありません。
前提モデルの違い です。

jQueryの前提

  • DOMを直接操作
  • $ はグローバル
  • 状態=DOM

Reactの前提

  • 状態が真実
  • DOMは結果
  • 直接操作すると破綻

両者が無秩序に混ざると、

  • $ is not defined
  • $ is not a function
  • 状態とDOMが乖離する

という表示画面とデータが乖離する事故が起きます。

共存の原則

jQueryを使用する場合は、必ず以下の形式でスコープを閉じ、React側の管理領域に侵食させないことが安定稼働の条件です 。
jQuery(function($){
  // jQueryはこのスコープ内だけで完結させ、グローバルを汚染しない
});
JavaScript
  • $ をローカルに閉じる
  • React側に侵食させない

混ぜないことが最大の最適化です。

webpack / npm が絡むと「本番だけ壊れる」理由

ここから話は ビルドの世界 に移ります。

npmとは何か

npmは、

  • JavaScriptライブラリの取得
  • 依存関係の管理

を行うツールです。
node_modules にすべてが展開されます。

webpackとは何か

webpackは、

  • 複数のJS
  • npm依存

ブラウザ向けに束ねる(bundle) ツールです。

現代のJS(ESM / JSX / TS)は、そのままでは動かないことが多く、ビルドが前提になります。

なぜローカルでは動くのか

  • node_modules が存在
  • 開発モード
  • SourceMap 有効
  • 多少の依存欠損を許容

なぜ本番で壊れるのか

  • ビルド成果物のみ配置
  • node_modules 不在
  • 読み込み順は WordPress に依存

ここで WordPress特有の罠 が発生します。

WordPressでは「依存解決の責任者」が違う

WordPressには wp_enqueue_script という公式の読み込み機構があり、下記を担っています 。

  • 読み込み順を保証
  • 依存関係を解決
  • 二重ロードを防止

webpackでReactをbundleし、WordPress側でも wp-element(React)を読み込むと、

  • React二重ロード
  • グローバル状態破綻
  • ブロックエディタが沈黙

Reactを二重に読み込んだ瞬間、エディタは静かに死にます🪦

それでは正しい設計原則は?

  • React / wp-element は WordPressに任せる
  • webpackでは externals 指定
  • 依存関係は wp_enqueue_script で宣言

ヘッドレスWordPressでは問題はどこに移るか

ヘッドレスWordPressとは

この瞬間、問題は PHP から ブラウザの制約 に移ります。

CORSと認証は「別物」だが同時に壊れる

CORSとは何か

CORS(Cross-Origin Resource Sharing)とは、異なるドメイン間での通信を、ブラウザがセキュリティのために制限する仕組みです。

サーバー側が許可を出していても、ブラウザ側で通信を破棄することがあります 。

認証(JWT、App Password等)とCORSは全くの別物です。

認証方式ごとの違い

方式特徴
JWTAuthorizationヘッダ必須 / CORS必須
App PasswordHTTPS必須 / 管理用途向き
CookieSameSite制約に注意

最重要ポイント

認証が正しくてもCORSが通らなければ失敗

CORSが通っても認証が誤っていれば失敗

これは AND条件 です。

本番JSトラブル時のチェックリスト

不具合が発生した際は、以下の順に確認してください 。

  1. Networkタブ:
    REST APIのJSONに余分な出力が混じっていないか 。
  2. Consoleタブ:
    Reactのエラー(Minified Error等)が出ていないか 。
  3. 環境再現:
    SourceMapが使えるローカル等の開発環境で再現するか 。
  4. 二重ロード:
    Reactが複数回読み込まれていないか 。
  5. 依存関係:
    wp_enqueue_script の依存定義が正しいか 。
  6. CORS/認証:
    ブラウザが通信を遮断していないか同時に確認 。

上級者Q&A:管理画面・ブロックエディタのJSトラブル実践編

Q1.PHPエラーもREST APIエラーも出ていないのに、保存だけが失敗します。どこを見るべきですか?

最初に確認すべきは、Networkタブに表示されるREST APIレスポンスの「生JSON」です。

WordPress REST APIでは、

  • PHPの処理が致命的エラーを起こしていない場合
  • warning / notice / 余分な出力が混入しても

HTTPステータスが 200 OK のまま返るケースがあります。

この場合、

  • PHPは成功している
  • しかしブラウザ側(React)がJSONを解釈できず失敗する

という状態になります。

チェックポイントは以下です。

  • レスポンス先頭・末尾に
    • notice
    • warning
    • HTMLタグ
    • 空白
      が混入していないか?
  • Consoleに 「Unexpected token < 」などが出ていないか?

これは
「PHPは正常、JSだけが失敗する」典型例です。

Q2.Minified React error が出ていますが、番号しか表示されません。本番環境でどう対処しますか?

原則として、本番環境での直接解析は行いません(行えません)。

理由は次の通りです。

  • 本番では SourceMap が無効・非公開なことが多い
  • minified bundle は人間が読む前提で作られていない

React公式・WordPress公式の実務でも、
再現環境(ローカル/ステージング)での解析が推奨されています。

WordPress公式

Gutenberg ブロック開発
https://developer.wordpress.org/block-editor/getting-started/
(“開発環境を整える” という公式ドキュメント)

React公式

開発環境セットアップ
https://react.dev/learn/installation
(ローカル開発サーバーで動作確認するのが前提)

正しい手順は、

  1. 本番と同じ構成をローカルまたはステージングで再現
  2. 開発モードで同じ操作を実行
  3. フルメッセージのReactエラーを確認

※例外として、SourceMapが公開されている場合のみ本番解析が可能です。

Q3.jQueryとReactが混在している既存テーマを、全面的に書き換えず安定させる方法はありますか?

あります。ただし条件付きです。

重要なのは 共存ではなく「責務の分離」 です。

  • jQuery
    • 管理画面外
    • 単発UI操作
    • DOM直接操作が前提
  • React
    • ブロックエディタ内部
    • 状態管理が前提

jQueryは必ず次の形でスコープを閉じます。

jQuery(function($){
  // jQueryはこの中だけで完結させる
});
JavaScript

Reactの管理下に
DOM直接操作を侵入させないこと が安定条件です。

これは WordPressコア自身が採用している設計とも一致します。

Q4.webpackでビルドしたJSが、本番のブロックエディタだけで壊れます。よくある原因は何ですか?

実務上、非常に多い原因の一つが React(wp-element)の二重ロードです。

原因としてよく見られるのは、

  • webpackでReactをbundleしている
  • WordPress側でも wp-element(React)をenqueueしている

という 責務の衝突 です。

この状態では、

  • Reactのグローバル状態が分断され
  • ブロックエディタが正常に初期化できなくなります

対策は明確です。

  • webpackではReactを externals 指定
  • 依存関係の解決は wp_enqueue_script に任せる

依存解決はWordPress側に一元化する
これが最も安全な設計です。

Q5.ヘッドレスWordPress構成で、APIは正常なのにフロントエンドだけが失敗します。何を疑うべきですか?

まず CORS → 認証の順で確認します。

重要なのは、CORSは

  • サーバーではなく
  • ブラウザ側で通信を遮断する仕組み

だという点です。

特にJWT認証では、

  • Authorization ヘッダ
  • preflight(OPTIONS)
  • Access-Control-Allow-Headers

が正しく設定されていないと、
認証以前に通信が破棄されます

この場合、

  • サーバー側ログに何も残らない
  • API自体は正常に見える

という状態になります。

Q6.JSエラーを放置すると、実務上いちばん危険なことは何ですか?

壊れた状態のデータがDBに保存される可能性があることです。

ブロックエディタでは、

  • ブロック属性
  • post meta

JSON構造として保存されます。

JS側で、

  • 状態欠損
  • 属性不整合

が起きた状態で保存されると、
壊れたデータがそのまま永続化されることがあります。

常にDBが壊れるわけではありませんが、
条件が揃うと 後からJSを直しても戻らない事故 になります。

このため、

JSエラーは
「画面の問題」ではなく
「DB事故の入口」

として扱う必要があります。

まとめ

最も警戒すべきは、「壊れた状態のデータがDBに保存されるリスク」にあります 。

ブロックエディタでは、各ブロックの属性や設定がJSON構造として保存されます 。JS側で不整合が起きた状態で保存が実行されると、不完全なデータがそのままDBに永続化されてしまいます 。

これは単なる「表示の不具合」ではありません。

ハッキングやマルウェアによる改ざんと、JSエラーによるデータ欠損は、DBから見れば同じ「意図しないデータの書き換え」です。

  • ハッキング/改ざん:
    悪意あるスクリプトがDB内のJSON構造を書き換え、バックドアを仕込む。
  • JSエラー:
    不具合のあるスクリプトがDB内のJSON構造を破壊し、サイトを機能不全にする。

どちらも「後からプログラムを直しても、壊れたデータは元に戻らない」という致命的な事故に直結します 。

JSエラーは「画面の問題」ではなく、「DB事故、あるいはセキュリティ侵害の入口」として扱うべき重大なサインなのです 。

ここまで把握して初めて、近年のWordPressトラブルを根本から解決できる上級者となります 。

次回、第5回では

「戻れない事故」を扱います。

マルウェア感染によるデータ改ざん、DB移転時のシリアライズ破壊など、JSの失敗や外部攻撃が「データベースへ永続化される瞬間」とその救出策について解説します 。

ココナラよりも安い!

ウェブナラはじめました!

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

ABOUT ME
WEBさん
WEBさん
WordPressの不具合をなおす人
あなたのお仕事をする時間を使ってITに関することを調べたり、トライしてみたりして、それでもうまくいかない。そんなことはありませんか? WEB先案内をご利用いただくと、困ったときにITの顧問としてあなたのITに関するお悩みにお答えし、サポートを行うことができます。
記事URLをコピーしました