タグアーカイブ トラブル解決

LiteSpeed Cacheでパージ成功してもキャッシュが残る原因と直し方

LiteSpeed Cacheでパージ成功してもキャッシュが残る原因と直し方

LiteSpeed Cacheで管理画面やWP-CLIから「Purge All(全キャッシュ削除)」を実行し成功メッセージが出ているにもかかわらず、公開ページがいつまでも古い内容のまま更新されない場合、プラグインのキャッシュ制御と実際に動作しているサーバーレベルのキャッシュ層との間に不整合が起きている可能性が高い。根本的には、LSCacheプラグインの設定最適化と、場合によってはプラグインを一時的に無効化しての強制リフレッシュが有効な解決策になる。

なぜ「全削除」に成功してもキャッシュが残り続けるのか

なぜ「全削除」に成功してもキャッシュが残り続けるのか

LiteSpeed Cacheのキャッシュ構造は多層的で、プラグインの管理画面と実際のキャッシュストレージが常に一対一で対応しているとは限らない。管理画面で「Purge All」を実行すると、プラグインは内部的にパージタグを生成し、LSWS(LiteSpeed Web Server)に対してキャッシュ削除の指示を出す。ここで成功メッセージが返ってくるのは、あくまで「指示が出せた」という意味であり、ディスクやメモリ上の実ファイルが完全に消えたことの保証にはならない。

まず試すべきプラグイン側の設定見直し

まず試すべきプラグイン側の設定見直し
修正前の状態
パージを実行しても、レスポンスヘッダーに x-litespeed-cache:hit が返ってくる。
x-litespeed-cache: hit
x-litespeed-cache-control: no-cache
修正後の状態
キャッシュヘッダーが miss になり、サーバーが動的生成に切り替わった。
x-litespeed-cache: miss
キャッシュヒットして古い内容が表示される  キャッシュミスで最新の内容が表示される

キャッシュ有効期限とブラウザキャッシュ設定の確認

まず、LSCacheプラグインの「キャッシュ」タブでTTL(Time To Live、キャッシュの有効期限)が極端に長く設定されていないか確認する。デフォルトは604800秒(1週間)だが、公開ページの更新頻度が高いサイトでは3600秒(1時間)程度に短くすることで、パージ操作の効果が出やすくなる。また「ブラウザキャッシュ」タブで、ブラウザ側のキャッシュ保持期間が長すぎると、サーバーのパージ後もユーザーのローカルキャッシュが優先されて古い表示になる。短期間に設定するか、問題切分け中は一時的に無効化(オフ)にする。

オブジェクトキャッシュとRedisの影響を見極める

RedisやMemcachedといった外部オブジェクトキャッシュを使っている環境では、LSCacheがページキャッシュを削除しても、データベースクエリの結果がオブジェクトキャッシュに残り、結果として同じ古い情報でページが再生成される。Redisを使っているなら、管理画面の「LiteSpeed Cache」→「オブジェクトキャッシュ」でステータスを確認し、「Purge Object Cache」を手動で実行する。それでも直らない場合は、問題の切分けとしてredis-cacheやRedis Object Cacheプラグイン自体を一度無効化し、LSCacheだけの状態でパージを試す。

サーバーレベルで強制的にキャッシュを削除する手順

プラグインの操作で改善しない場合、LiteSpeed Web Serverが保持しているキャッシュをOSレベルで手動削除する。特に、LSCacheプラグインが生成したキャッシュ情報と、LSWSの内部キャッシュマップがずれてしまった場合に有効だ。

サーバーレベルの強制キャッシュクリア手順
STEP 1 SSHでサーバーにログインし、LSWSのキャッシュディレクトリを特定する
STEP 2 LSWSを完全停止し、スワップファイルとキャッシュファイルをすべて削除する
STEP 3 LSWSを起動し、LSCacheプラグインの「Purge All」を再度実行する
STEP 4 ブラウザのシークレットモードで動作を確認する

ディスクキャッシュの格納場所と削除コマンド

SSHでサーバーに接続し、まずLSWSのキャッシュパスを特定する。デフォルトでは /tmp/lshttpd/ または /usr/local/lsws/cachedata/ 以下にキャッシュが格納されている。LSCacheプラグインの「CDN/キャッシュ設定」にある「キャッシュルートパス」を確認すると確実だ。

次に、LSWSを完全に停止する。systemctl restart lsws や管理画面からのグレースフルリスタートではプロセスがクリアされず、内部のキャッシュマップが生き残る。以下の手順で、キャッシュディレクトリを物理的に空にしてから再起動する。

# LSWSを完全停止
/usr/local/lsws/bin/lswsctrl stop

# キャッシュディレクトリとスワップを完全に削除
rm -rf /tmp/lshttpd/swap/*
rm -rf /tmp/lshttpd/cache/*

# LSWSを起動
/usr/local/lsws/bin/lswsctrl start

起動後、WordPress管理画面からLSCacheの「Purge All」を実行し、ブラウザのシークレットウィンドウ(または開発者ツールでキャッシュを無効化した状態)で動作を確認する。x-litespeed-cache ヘッダーが miss になっていれば成功だ。

どうしても治らない場合の一時的切り分け

上記の手順を実行しても、ベアURL(パラメータなしの通常アクセス)だけが古いキャッシュを返し続ける場合、LSCacheプラグイン自体がリクエスト段階でキャッシュの再取得を意図せず阻害している可能性が高い。この状況は、特定の条件下でLSCacheプラグインがブラウザやリバースプロキシに強力なCache-Controlヘッダーを設定し、サーバー側でミスになってもCDNやブラウザが古いデータを返し続けるケースだ。

最終的な切分けとして、LSCacheプラグインを5分〜10分間だけ完全に無効化する。無効化後に即座にキャッシュが更新されるなら、LSCacheプラグインの内部ロジックまたは設定が主因であると特定できる。プラグインを再有効化した後、デフォルト設定へのリセットや、問題を再現させた設定項目を一つずつ絞り込む。

よくある質問

クエリ文字列を付けるとキャッシュがバイパスされる理由は?

LiteSpeed Cacheは、URLにパラメータ(?=xxx)が付与されたリクエストを、デフォルトでキャッシュ対象外とみなす。そのためベアURLでは x-litespeed-cache:hit で古いキャッシュが返っているのに、/?v=2 のような文字列を付けると miss となり、動的に生成された最新ページが表示される。

サーバーを再起動できない共有サーバーではどう対処すればよいか

多くの共用サーバーではSSHやLSWSの制御権限が制限されている。この場合、LSCacheプラグインの「ツールボックス」→「Purge All」を実行し、即座にプラグインを無効化する。その後「LiteSpeed Cache」を再有効化し、デフォルト設定へのリセットを試す。サーバー側のキャッシュディレクトリに触れない環境では、この手順が最も確実な強制リセットになる。

パージ後のキャッシュ再生成を防ぎたい場合の設定は?

公開前のプレビューや検証でキャッシュを完全に止めたい場合、LSCacheプラグインの「キャッシュ」→「キャッシュを有効化」のトグルを一時的にオフにする方法が最も確実だ。ただしこの設定はサイト全体のパフォーマンスに影響するため、検証後は必ずオンに戻し、特定のページだけ除外したい場合は「URI 除外」機能を使う。

この記事のポイント

  • LSCacheのパージ成功表示が実キャッシュ削除の保証にはならない
  • サーバーレベルでディスクキャッシュを直接削除すると治るケースが多い
  • Redisなどの外部オブジェクトキャッシュも同時に削除する必要がある
  • クエリ文字列でバイパスされる現象はLSCacheの正常動作だが、ベアURLが古いのは異常
  • どうしても治らなければ、プラグインの一時無効化で原因をLSCacheに特定できる
WooCommerceバリエーション商品のカート追加で重大エラーが出る時の修正方法

WooCommerceバリエーション商品のカート追加で重大エラーが出る時の修正方法

WooCommerce のブロックベースカートでバリエーション商品を追加した際に「woo-min-max-quantity-step-control-single」プラグインが原因で「このサイトで重大なエラーが発生しました」と表示される場合、原因はプラグインが商品オブジェクトの取得失敗を考慮していないことだ。該当ファイルの PHP コードに数行の修正を加えればエラーを回避できる。

なぜブロックカートでバリエーション商品だけエラーになるのか

エラーログを確認すると、問題はプラグインの min-max-controller.php 872行目付近で発生している。この行では wc_get_product() で商品情報を取得した直後に ->get_id() を呼んでいるが、wc_get_product() は対象の商品が見つからなかった場合に false を返す。ブロックベースのカート(Store API)経由でバリエーション商品が追加されると、この関数がまれに false を返す状況が発生する。プラグインのコードはその可能性をまったく想定しておらず、結果として「Call to a member function get_id() on false」という致命的な PHP エラーに直結している。

エラーを根本解決するためのコード修正手順

エラーを根本解決するためのコード修正手順
STEP 1 FTP や管理画面から該当ファイルを探す
STEP 2 872 行目付近のコードを確認し false チェックを追加する
STEP 3 修正したファイルをサーバーにアップロードする

該当ファイルを開き 872 行目周辺を特定する

FTP クライアント、またはレンタルサーバーのファイルマネージャーで、以下のパスにあるファイルを開く。WordPress 管理画面の「プラグイン」→「プラグインファイルエディター」から編集するのはできるだけ避ける。エディター画面で編集ミスをするとサイト全体が停止するリスクがあるためだ。

/wp-content/plugins/woo-min-max-quantity-step-control-single/includes/min-max-controller.php

使用しているエディタで行番号表示を有効にし、872 行目付近まで移動する。エラーログに表示されているとおり、->get_id() を直接呼んでいる箇所を探そう。

修正前と修正後のコードを比較する

修正前(エラー) Before
$product = wc_get_product( $product_id );
$min = $product->get_id();
修正後(安全) After
$product = wc_get_product( $product_id );
if ( ! $product || ! is_a( $product, ‘WC_Product’ ) ) {
    return;
}
$min = $product->get_id();
エラー状態  修正後

PHP コード修正の内容と意味

修正の核心は、$product が有効なオブジェクトかどうかを事前に検証することだ。

! $productwc_get_product()false を返した場合を検出する。is_a( $product, 'WC_Product' ) は、取得できたとしてもそれが WooCommerce の正規の商品オブジェクトであることを確認する。どちらかの条件を満たさなければ return で処理を中断し、以降の ->get_id() が呼ばれないようにする仕組みだ。

このガード節を入れることで、ブロックカート経由でどういった商品情報が渡ってきても、致命的なエラーにはならなくなる。

修正してもエラーが直らない場合の確認点

まれに、修正だけでは根本解決しないケースがある。以下の点も確認してみてほしい。

WooCommerce データベースのクリーンアップを実行する

「WooCommerce」→「ステータス」→「ツール」タブに移動し、「WooCommerce トランジェントをクリア」と「期限切れのトランジェントを削除」を実行する。キャッシュが原因で商品情報が正しく取得できていない場合に効果がある。

最小最大数量プラグインのバージョンと WooCommerce のバージョンを確認する

プラグインが最新の WooCommerce や Store API に対応していない可能性がある。プラグインの公式ページで対応バージョンを確認し、場合によっては別の数量制御プラグインを検討する必要がある。修正を加えても根本的な設計の問題で他の不具合が発生する場合は、開発者に修正リクエストを送りつつ、一時的に従来のショートコードカート([woocommerce_cart])へ切り戻すことも視野に入れる。

よくある質問

この問題はブロックカートだけに発生するのか

主にブロックベースのカートとチェックアウト(Store API)で発生する。従来のショートコードカートではエラーが出ないことも多いが、プラグインコードに潜在的な問題があるため、修正しておく方が安全だ。

プラグインがアップデートされたら修正は消えるか

消える。今回の修正はプラグインのコアファイルを直接編集しているため、プラグインにアップデートが配信されると編集内容は上書きされる。アップデート後に同様のエラーが再発した場合は、再び同じ手順で修正するか、開発者が修正を取り込むまでアップデートを控える必要がある。

子テーマの functions.php でこのエラーを回避できるか

難しい。今回のエラーはプラグイン内部の特定の行で発生しており、かつ商品取得のロジック周辺にフックが用意されていない限り、テーマファイル側から割り込んで防御することはできない。直接ファイルを編集する今回の方法が最も確実な対処法になる。

修正中にサイトが壊れてしまった場合の直し方は

FTP でサーバーにアクセスし、修正前にバックアップしておいた min-max-controller.php を上書きアップロードする。バックアップがない場合は、プラグインを一度削除して再インストールするのが早い。ただし、プラグインの設定内容はあらかじめメモしておく必要がある。

この記事のポイント

  • エラー原因はプラグイン内での get_id() 呼び出し前に false チェックがないこと
  • 修正対象は min-max-controller.php の 872 行目付近
  • wc_get_product()false を返す状況を考慮したガード節を追加する
  • ブロックカート(Store API)利用時に特に発生しやすい PHP エラーへの対処法
  • 直接ファイルを修正するため、プラグインのアップデートで編集が上書きされる点に注意
WordPressカスタムHTMLブロックが編集画面で消える原因と直し方

WordPressカスタムHTMLブロックが編集画面で消える原因と直し方

WordPress のブロックエディターでカスタム HTML ブロックを保存後に編集画面を開き直すと、ブロックの中身がまるごと消えて空欄に見える現象は、Gutenberg の React 側パーサーが HTML 構造を正しく解析できずに描画を放棄しているのが主な原因だ。script タグや閉じタグのない要素、複雑なインラインスタイルなどが引き金になる。

なぜカスタムHTMLブロックが編集画面で空になるのか

なぜカスタムHTMLブロックが編集画面で空になるのか

フロントエンドでは正しく表示されるのに、管理画面のブロックエディターだけで中身が空になるのは、データそのものはデータベースに保存されている証拠だ。コードエディターモードに切り替えれば、貼り付けた HTML が消えずに残っているのが確認できる。この現象が起こるのは、ブロックエディターがビジュアルモードでブロック内容を再表示するときに、DOM パーサーが特定の HTML を「壊れた構造」と判断してレンダリングを飛ばしてしまうからだ。

具体的には、Gutenberg が内部的に使用している React の DOM レンダリング機構が、管理画面の安全な枠組みの中で処理できないタグや構文に遭遇すると、そのブロック全体を安全のためにスキップする。結果として視覚的には空のブロックに見えるが、データベースの post_content には元のコードがそのまま格納されている。

カスタムHTMLブロックの中身が消える原因を特定する手順

カスタムHTMLブロックの中身が消える原因を特定する手順

まず、どの部分が問題を引き起こしているのかを切り分ける。以下の手順で原因箇所を絞り込む。

ブロックエディターのコードエディターモードで現状を確認する

編集画面右上の「︙」メニューから「コードエディター」を選択すると、ビジュアル表示ではなく生の HTML 構造が表示される。カスタムHTMLブロック内のコードがここで確認できれば、データは失われていない。このとき、Markdown 記法でブロック境界を示す <!-- wp:html --><!-- /wp:html --> のコメント行の内側にコードが残っているかを確かめる。

HTMLを最小単位に分解して原因のタグを特定する

ブロックに貼り付けた HTML を、1つのタグ単位で分割してカスタムHTMLブロックに1つずつ入れ直す。たとえば script タグ、style タグ、空要素(<div></div> など)、インラインイベントハンドラ(onclick など)をそれぞれ別のブロックに分けて保存し、再読み込み時に消えるかどうかをテストする。問題を起こすタグが特定できれば、その部分だけ別の実装方法に切り替えられる。

プラグイン競合の可能性を調べる

特定のプラグインがブロックエディターの動作に干渉して、カスタムHTMLブロックの描画を阻害しているケースもある。特にエディター拡張系のプラグインや、セキュリティ目的でスクリプトをフィルタリングするプラグインが入っている場合は、すべてのプラグインを一度無効化して標準テーマに切り替え、問題が再現するか確認する。プラグインが原因であれば、1つずつ再有効化して犯人を特定する。

カスタムHTMLブロックを正常に表示させる具体的な修正手順

カスタムHTMLブロックを正常に表示させる具体的な修正手順

原因が特定できたら、次は実際にブロックを正常に表示させる。script タグや複雑な HTML 構造が原因だった場合、以下のアプローチで回避できる。

STEP 1 原因となっているタグを特定する(script タグなど)
STEP 2 script タグはカスタムHTMLブロックの外に出す
STEP 3 複雑なHTMLはACFのフィールドやウィジェットで管理する
STEP 4 コードエディターモードで編集する運用に切り替える

script タグや iframe はカスタムHTMLブロックではなく適切な場所に配置する

Gutenberg のカスタムHTMLブロックは、セキュリティ上の理由から script タグの実行を制限している。また、ビジュアルエディターでの再レンダリング時に script タグを含むブロックを空として扱う挙動が確認されている。JavaScript を埋め込みたい場合は、カスタムHTMLブロックではなく、functions.php に wp_enqueue_script で登録するか、専用のコード埋め込みプラグインを使う。iframe も同様に、エディターのプレビューで空白になることがあるため、フロントエンドのみで描画される仕組みを検討する。

閉じタグのない空要素を見直す

カスタムHTMLブロックに <div></div> のような中身のない空タグや、閉じタグを省略した要素が含まれていると、Gutenberg のブロックパーサーが構造を正しく解釈できずにブロック全体をスキップすることがある。空の div や span は削除するか、&nbsp; を入れて実体を持たせる。とくに WordPress の自動整形機能(wpautop)が余分な p タグや br タグを挿入することで、意図しない空要素が生まれることもある。

複雑なHTML構造はカスタムフィールドやショートコードに置き換える

テーブルやフォーム、装飾を多用したマークアップは、カスタムHTMLブロック1つにまとめるよりも、ACF(Advanced Custom Fields)のテキストエリアフィールドや、ショートコード化して出力する方が安定する。とくにクライアントが自分で編集する前提のサイトでは、カスタムHTMLブロックを直接触らせると今回のようなトラブルが再発しやすい。テーマ側でテンプレートパーツとして管理し、投稿画面では入力欄だけを提供する設計が安全だ。

今後同様のトラブルを防ぐための運用ポイント

今後同様のトラブルを防ぐための運用ポイント

カスタムHTMLブロックに貼り付ける前にコード検証を行う

外部の HTML スニペットをそのまま貼り付ける前に、W3C のバリデーターや VSCode の構文チェック機能でタグの閉じ忘れや文法エラーがないかを確認する。コピー元の Web ページから取得したコードには、不要な属性や非推奨のタグが混じっていることが多い。貼り付け前に一度テキストエディターにペーストし、明らかな問題を取り除いてからブロックに入力する習慣をつける。

WordPress と Gutenberg を最新バージョンに保つ

Gutenberg プラグインを単体でインストールしている場合は、定期的に更新することでブロックパーサーの改善や既知の不具合修正が適用される。コア組み込みのブロックエディターであっても、WordPress 本体のアップデートによってパースエンジンの挙動が改良されることがある。編集画面でカスタムHTMLブロックが空になる現象の一部は、過去のバージョンで修正されたバグに起因している可能性もあるため、まずは最新の状態であることを確認する。

どうしても必要な場合はコードエディターモードを常用する

ビジュアルエディターで空になってしまう HTML をどうしてもページに残したいときは、編集時にコードエディターモードに切り替えて作業する方法が最終的な回避策になる。データベースにコードが正しく保存されているなら、コードエディター表示では常に中身が確認できる。手間は増えるが、複雑なマークアップや埋め込みコードを扱うページでは、あらかじめこの運用を前提にしておくとトラブルが起きても編集が止まらない。

よくある質問

カスタムHTMLブロックの中身は完全に消えたのか

ビジュアルエディターでは空に見えても、コードエディターモードに切り替えると HTML が残っていることがほとんどだ。データベースの post_content にも保存されているため、失われたわけではない。

プラグインをすべて無効化しても直らない場合はどうすればいいか

テーマの functions.php や使用中の子テーマがエディターの動作に干渉している可能性がある。標準テーマ(Twenty Twenty-Five など)に一時的に切り替えて再現するか確認し、テーマ側のフィルターやアクションを調査する。

script タグをカスタムHTMLブロックで使う正しい方法はあるか

原則としてカスタムHTMLブロック内の script タグは推奨されない。管理画面でのレンダリング問題に加え、セキュリティプラグインやサーバー側のフィルターで除去されるリスクもある。どうしても必要な場合はショートコード化するか、wp_enqueue_script でテーマに登録するのが安全だ。

ビジュアルエディターで空白になる特定の HTML タグの一覧はあるか

公式の一覧は存在しないが、script タグ、style タグ、iframe、object、embed、空の div や span、コメントアウト行、複雑に入れ子になったインラインスタイル付き要素などが報告されている。問題が起きたら該当タグを一つずつ検証するのが確実だ。

ビジュアルエディターで空になる現象は Gutenberg のバグなのか

仕様とバグの両面がある。script タグの実行制限はセキュリティ上の意図的な制限であり、空要素のパース失敗はブロックエディターの改善が期待される領域だ。WordPress コアのバージョンアップによって挙動が変わることもあるため、最新バージョンへの更新が有効な場合が多い。

この記事のポイント

  • カスタムHTMLブロックが空に見えてもデータはデータベースに残っている
  • script タグや空要素、閉じタグ省略がパース失敗の主原因
  • コードエディターモードで中身を確認し原因タグを特定する
  • 複雑な HTML はカスタムフィールドやショートコードで管理する
  • WordPress と Gutenberg の最新化で改善するケースがある
WooCommerce Taxが配送先住所を無視する原因と修正手順

WooCommerce Taxが配送先住所を無視する原因と修正手順

WooCommerceの自動税計算(WooCommerce Tax)が配送先住所を無視して店舗住所の税率を適用し続ける場合、設定のキャッシュか配送先住所の認識不良が原因だ。税計算の基準を再確認し、プラグインのトランジェントデータを手動で削除すれば、多くのケースで正しい税率に戻る。

配送先住所ではなく店舗住所の税率が使われる原因

配送先住所ではなく店舗住所の税率が使われる原因

WooCommerce Tax(旧称 WooCommerce Shipping & Tax)は、有効化すると TaxJar の自動税率データベースを参照して税額を算出する。管理画面の「WooCommerce > 設定 > 税」で「顧客の配送先住所に基づいて計算する」を選択しているにもかかわらず店舗住所の税率が使われるのは、次のいずれかが起きていると考えられる。

  • 税計算の基準設定が実際には店舗住所のまま保存されていない、または別のフィルターで上書きされている
  • プラグインが内部に保持するトランジェントキャッシュが古い設定を返し、配送先住所を無視している
  • チェックアウト時に配送先住所が正しくシステムに渡っていない(テーマや他のプラグインによる競合)
  • WooCommerce Tax が店舗の税ネクサス(課税拠点)を元にした「オリジンベース課税」のルールを配送先住所より優先してしまっている

特に最後の点は、米国のように州ごとにオリジンベース/デスティネーションベースの課税方式が異なる地域で混乱しやすい。日本国内のオンラインショップでは基本的に配送先住所の税率(消費税10%または軽減税率8%)が使われるべきだが、WooCommerce Tax が海外の課税ロジックを引きずっている場合もあり、実際に「店舗住所を変えると税率が変わってしまう」といった現象が報告されている。

誤った動き
配送先住所「大阪市 530-0001」(税率8.25%のはず)

適用される税率 → 店舗住所「東京都 100-0001」の税率10%
正しい動き
配送先住所「大阪市 530-0001」

適用される税率 → 配送先住所の8.25%
誤った状態  修正後

このデモのように、配送先住所を正しく入力していても、店舗住所の税率だけが繰り返し使われるのが典型的な症状だ。

税計算の基準が本当に配送先住所になっているか再確認する

税計算の基準が本当に配送先住所になっているか再確認する

まず根本的な設定ミスがないか、管理画面をチェックする。

STEP 1 WooCommerce > 設定 > 税 を開く
STEP 2 「配送先住所に基づいて計算する」が選択されているか確認
STEP 3 「自動税計算を有効にする」のチェックを一時的に外して保存し、再度チェックを入れて保存

設定画面上は正しく見えていても、内部的に値がロックされている場合がある。STEP 3 のように一度無効化して再保存することで、WooCommerce Tax の内部キャッシュをリセットできる。

トランジェントキャッシュを手動で削除する

WooCommerce Tax は API から取得した税率データを WordPress のトランジェント(一時キャッシュ)に保存している。このキャッシュが古いままだと、配送先住所が変わっても最初に引いた店舗住所のレートを返し続けることがある。

データベースを直接操作せずにキャッシュをクリアする方法

  • WooCommerce > ステータス > ツール に移動する
  • 「WooCommerce トランジェントをクリア」を実行する
  • さらに「顧客セッションをクリア」も実施する
  • 必要に応じて、WooCommerce Tax プラグインを無効化してから削除し、再度インストールして有効化する

再インストール時には、プラグインが新しい API キーを取得し、税設定が初期化される。その後、必ず「WooCommerce > 設定 > 税」で「配送先住所に基づいて計算する」を再設定する。

配送先住所の受け渡しをデバッグモードで検証する

配送先住所の受け渡しをデバッグモードで検証する

テーマや他のプラグインの影響で、チェックアウト画面から正しい配送先住所が WooCommerce Tax に渡っていない可能性もある。WooCommerce のデバッグモードを有効にして、税計算の内部ログを確認する。

設定 wp-config.php に define('WP_DEBUG', true); を追加
確認 チェックアウト時にデバッグログを Watch
調査 TaxJar API へのリクエストに正しい配送先 ZIP が渡っているか確認

WooCommerce > ステータス > ログ に、woocommerce-taxtaxjar のログファイルが生成される。配送先住所ではなく店舗住所が送信されているようであれば、テーマの functions.php やカスタムコードが住所情報を改変していないか精査する。

応急的に店舗住所を「配送先住所」と同じ扱いにするフィルター

どうしても自動税計算が配送先住所を認識せず、緊急で正しい税率を適用しなければならない場合、WordPress のフィルターフックを使って一時的に配送先住所を強制的に税計算に使わせることもできる。

add_filter( 'woocommerce_tax_based_on', function( $base ) {
    if ( is_checkout() || is_cart() ) {
        return 'shipping';
    }
    return $base;
});

このコードを子テーマの functions.php に追加すれば、カート・チェックアウト画面では常に配送先住所ベースの計算が強制される。ただし、根本原因の解決にはならないため、あくまで応急策として利用する。

よくある質問

よくある質問

WooCommerce Tax を再インストールしても直らないのはなぜか

再インストールだけでは、データベースに残ったトランジェントや設定値が削除されないことがある。プラグインを削除した後に「WooCommerce > ステータス > ツール」からトランジェントを完全クリアし、その上で再インストールする必要がある。

配送先住所が正しく入力されているのに税率が変わらないのはどうしてか

WooCommerce Tax は TaxJar API に配送先の ZIP コードと国・州の情報を送り、税率を取得する。このとき、ZIP コードが実在しないか API が認識できない場合、フォールバックとして店舗住所の税率を返す仕様がある。テストする住所が実在するか、郵便番号のフォーマットが正しいかを再確認する。

WooCommerce Tax を使わずに日本国内の税率を正確に計算するにはどうすればよいか

日本国内のオンラインショップで消費税のみを扱うなら、自動税率プラグインを無効化し、WooCommerce 標準の税率設定で「標準税率(10%)」と「軽減税率(8%)」を手動で登録する方が安定する。配送先住所の県や市町村による税率差分が不要なケースが大半のため、あえて自動計算を導入する必要はない。

テスト注文を何度も行っても税額が変わらない場合の最終確認事項は

テスト注文時には、必ずブラウザのシークレットウィンドウを使い、サイトのキャッシュやセッションの影響を排除する。また、カートの計算がセッション情報に依存するため、住所を変えるたびにカートを空にしてから再度商品を追加する。

特定の州や地域でオリジンベース課税のせいで税率が店舗住所になることはあるのか

米国の一部の州では、店舗所在地と配送先の両方が同じ州内にある場合、店舗所在地の税率を適用するオリジンベース課税が採用されている。しかし、WooCommerce Tax は州ごとの課税方式を自動で判別するわけではなく、設定上のトラブルでこの現象が起こることがある。日本のショップでは関係ないが、海外向けに販売する場合は注意が必要だ。

この記事のポイント

  • 自動税計算が配送先住所を無視するのは、設定キャッシュか住所の受け渡し不良が主な原因
  • 「WooCommerce > 設定 > 税」の計算基準を再確認し、無効化→再有効化で内部リセットを試す
  • トランジェントキャッシュを手動クリアし、必要ならプラグインの再インストールを行う
  • デバッグログで TaxJar API へのリクエスト内容を検証する
  • 日本国内のみのショップなら自動税率をやめ、標準税率を手動設定する方が安定する
Booking Calendar更新後にサイトが壊れた時の原因と直し方

Booking Calendar更新後にサイトが壊れた時の原因と直し方

Booking Calendar プラグインを 11.4.1 から 11.4.2 へ更新した直後にサイトが壊れた場合、無料版(Booking Calendar)と有料版(Booking Calendar Pro または Booking Manager)のバージョン不一致が主要因だ。手動で両方を同一の最新バージョンに揃え、かつ Pro 版のライセンスを再適用すれば復旧できる。

なぜバージョン 11.4.2 への更新でサイトが壊れたのか

なぜバージョン 11.4.2 への更新でサイトが壊れたのか

Booking Calendar は無料版(WordPress.org 配布)と、追加機能を提供する Pro 版(開発元サイトで購入)が連携して動作する設計になっている。無料版は管理画面の「プラグイン」から自動更新される一方、Pro 版は手動で更新する必要がある。両者のバージョンが食い違うと、共有する関数やデータベース構造に不整合が生じ、PHP の致命的エラーを引き起こして画面が表示されなくなる。

とくに 11.4.2 では内部 API の変更が加えられており、Pro 版が旧バージョンのまま無料版だけを更新すると競合が起きやすい。この状態で WordPress の「このサイトで重大なエラーが発生しました」というメッセージが表示されたり、管理画面にアクセスできなくなったりする。

サイトを元に戻す具体的な手順

サイトを元に戻す具体的な手順

以下の手順で、無料版と Pro 版を安全に最新へ揃える。作業前に必ずサイト全体のバックアップを取得しておく。

STEP 1 FTP またはホスティングのファイルマネージャで /wp-content/plugins/ にアクセスする
STEP 2 無料版と Pro 版の両方のフォルダを一時的にリネームして無効化する(例: bookingbooking_old
STEP 3 無料版を WordPress.org から最新版(11.4.2)で再インストールし有効化する
STEP 4 開発元サイトから Pro 版の最新をダウンロードし、管理画面からアップロードして有効化、ライセンスキーを再入力する

プラグインフォルダを特定して無効化する

サイトが壊れて管理画面に入れない場合は、FTP(File Transfer Protocol)クライアントやレンタルサーバーのファイルマネージャを使う。/wp-content/plugins/ ディレクトリ内に、無料版(通常は booking または booking-calendar)と Pro 版(booking-calendar-prowpdev-booking など)のフォルダが存在する。両方をリネームすれば、WordPress はプラグインを強制的に無効化し、サイトが最低限の状態で表示されるようになる。リネーム後のフォルダ名は削除せず控えておく。

無料版を最新にして Pro 版を再適用する

管理画面にアクセスできる状態になったら、プラグイン一覧画面で一度 Booking Calendar を削除する。削除しても予約データはデータベースに保持されるため、消えることはない。その後「新規追加」から再度 Booking Calendar 11.4.2 をインストールし有効化する。

続いて開発元サイト(wpbookingcalendar.com)のアカウントページから、無料版と同一バージョン(11.4.2)に対応した Pro 版の ZIP ファイルをダウンロードする。管理画面の「プラグイン」→「新規追加」→「プラグインのアップロード」から ZIP を投入し、有効化後にライセンスキーを入力すれば復旧が完了する。Pro 版の最新ファイルが入手できない場合は、開発元のサポートへ直接更新ファイルを依頼する。

どうしても復旧できない場合の最終手段

Pro 版の最新 ZIP が手元になく、サイトのダウンタイムが許容できない状況では、無料版を旧バージョン(11.4.1)にダウングレードする選択肢もある。WordPress.org のプラグインページにある「以前のバージョン」から 11.4.1 の ZIP を入手し、FTP で手動上書きすれば以前の動作に戻せる。ただしセキュリティ修正が含まれている可能性があるため、この状態は恒久的な対策にはならず、早期に Pro 版を最新化する必要がある。

再発を防ぐための運用ルール

再発を防ぐための運用ルール

Booking Calendar のように無料版と有料版が連動するプラグインは、無料版の自動更新をオフにするか、更新前に必ず Pro 版の対応バージョンがリリースされているかを確認する習慣をつける。開発元のチェンジログやメーリングリストを購読しておくと、更新のタイミングを逃さない。

また本番環境に直接適用する前に、ステージング環境(本番と同一構成のテストサイト)で無料版と Pro 版の同時更新を試すのが最も確実な予防策になる。レンタルサーバーのステージング機能を使うか、WP Staging のようなプラグインで簡易的なテスト環境を用意できる。

よくある質問

Pro 版の最新ファイルがアカウントページに見当たらない場合はどうすればよいか

開発元の公式サイトにある問い合わせフォームまたはサポートチケットから、Pro 版の最新 ZIP ファイルを直接依頼する。購入時のメールアドレスやライセンスキーを記載すれば、通常は数営業日以内にダウンロードリンクが提供される。

フォルダをリネームしたがサイトがまだ壊れている

キャッシュ系プラグインや CDN(コンテンツデリバリネットワーク / 配信網)が古いエラー画面を配信し続けている可能性がある。サーバー側のキャッシュをすべてクリアし、ブラウザのシークレットモードで確認する。また wp-content/mu-plugins/ に手動で入れたファイルが競合していないかも調べる。

ライセンスキーを入力しても Pro 版の機能が有効にならない

ライセンスキーが旧バージョン向けのまま失効している可能性がある。開発元のマイページでキーを再発行するか、サポートにキーのリセットを依頼する。ドメインを変更した場合もライセンスの再割り当てが必要になる場合がある。

この記事のポイント

  • Booking Calendar 11.4.1 から 11.4.2 への更新障害は無料版と Pro 版のバージョン競合が原因
  • FTP で両方のプラグインフォルダをリネームし強制無効化して管理画面へ復帰
  • 無料版は削除後に 11.4.2 を再インストール、Pro 版は開発元から同一バージョンを入手
  • Pro 版がすぐ用意できない場合は無料版のみ旧バージョン 11.4.1 に戻す応急処置も可能
  • 再発防止には無料版の自動更新を止め、Pro 版のリリース確認後に揃えて更新する
WordPressをサブフォルダにインストールするとREST APIが404になる原因と直し方

WordPressをサブフォルダにインストールするとREST APIが404になる原因と直し方

WordPressをサブフォルダにインストールしている環境で、REST APIのエンドポイントが404エラーを返す場合は、プラグインがサブフォルダを考慮せずにAPIのURLを生成しているバグが原因だ。該当プラグインを最新版に更新するか、パーマリンク設定のリフレッシュで解決する。

なぜサブフォルダ環境でプラグインのAPIが404になるのか

なぜサブフォルダ環境でプラグインのAPIが404になるのか

WordPressをドキュメントルート直下ではなく/blog/siteのようなサブフォルダにインストールした場合、REST APIのベースURLはhttps://example.com/subfolder/wp-json/となる必要がある。ところが一部のプラグインは、内部でAPIのURLを組み立てる際にこのサブフォルダを考慮しておらず、https://example.com/wp-json/...のようにルート直下を指してしまう。その結果、実在しないパスへのリクエストとなり404が返る。

今回のケースでは、プラグインが独自に追加したエンドポイント/profeedwp/v1/linkedin/company-posts/smartに対して、サブフォルダを含まない不完全なURLでリクエストを発行していた。同様の問題は、テーマや他のプラグインがrest_url()関数を正しく使わずにハードコードしたパスを参照している場合にも起こる。

解決手順

解決手順

まず簡単かつ即効性のある方法として、問題のプラグインを最新版へ更新する。次に、WordPressのパーマリンク設定をリセットし、REST APIのルートURLが正しく再構築されるか確認する。これで直らない場合は、手動でrest_url()が返す値を検証し、他のプラグインとの競合を調べる。

STEP 1 問題のプラグインを最新版に更新する
STEP 2 パーマリンク設定をリセットして API ルートを再構築する
STEP 3 rest_url() の戻り値を検証し、サブフォルダが含まれるか確認する
STEP 4 全プラグインを無効化して競合を切り分ける

プラグインを最新版に更新する

本件ではバージョン1.6.10で修正が行われている。管理画面の「プラグイン」→「インストール済みプラグイン」から対象プラグインを確認し、更新が表示されていれば適用する。更新が出ていない場合は、一度プラグインを削除して再インストールするか、開発元の公式ページから修正版がリリースされていないか確認する。

パーマリンク設定をリセットする

プラグインの更新で直らなかった場合、パーマリンク構造の再保存でWordPress内部のルーティングをリフレッシュできる。「設定」→「パーマリンク」を開き、現在選択されている設定をそのままの状態で「変更を保存」をクリックする。これにより.htaccessの再生成と、REST APIのルート定義が再構築される。サブフォルダ環境では特に、リライトルールが正しくサブフォルダをプレフィックスとして含む必要があるため、この一手順で解決するケースが多い。

rest_url() の戻り値を検証する

根本原因がプラグイン側のURL組み立てにあるかどうかを切り分けるには、WordPressが正しいREST APIのルートURLを返しているかを確認する。テーマのfunctions.phpなどに次のようなテストコードを一時的に追加する。

add_action('wp_footer', function() {
    echo '<!-- REST URL: ' . esc_url(rest_url()) . ' -->';
});

サイトのフッター部分のHTMLソースに出力されたURLがhttps://example.com/subfolder/wp-json/の形式になっていれば、WordPress本体の認識は正しい。もし/subfolderが欠落している場合は、wp-config.phpWP_HOMEWP_SITEURLが正しくサブフォルダを含んだ値で定義されているか確認する。

全プラグインを無効化して競合を切り分ける

それでも404が解消しない場合、別のプラグインがREST APIのルーティングに干渉している可能性がある。すべてのプラグインを一括で無効化し、問題のエンドポイントにアクセスして200番台のレスポンスが返るかテストする。正常動作が確認できたら、プラグインを1つずつ有効化して原因のプラグインを特定する。キャッシュ系プラグインやセキュリティプラグインは、REST APIへのリクエストをブロックしたり、URLを書き換えたりする設定項目を持つことがあるため、該当するプラグインの設定もあわせて確認する。

よくある質問

サブフォルダにインストールする際にwp-config.phpで注意すべき点は?

WP_HOMEWP_SITEURLの定数をhttps://example.com/subfolderのようにサブフォルダを含めて明示的に定義しておくと、サイトURLの誤認識を防げる。wp-config.phpに記述しなければならないわけではないが、マルチサーバー構成やリバースプロキシの背後で運用する場合は特に有効だ。

REST APIの404エラーはどのようにデバッグすればいいか?

ブラウザのデベロッパーツールのネットワークタブで、実際に送信されたリクエストURLを確認する。サブフォルダが欠落したURLでリクエストが発生している場合は、呼び出し元のJavaScriptファイルやPHPコードでURLの組み立て方をチェックする。rest_url()を使わずにハードコードされたパスが原因であることが多い。

プラグインを更新しても問題が再発する場合は?

修正パッチが適用されたバージョンでも、キャッシュの残存やデータベースに保存された古い設定値が原因で再発することがある。プラグインを完全に削除したあと、wp_optionsテーブルに残っている該当プラグインのオプションを手動で削除し、最新版を再インストールすると改善する場合がある。

サブフォルダ環境でなくてもAPIが404になる原因は?

パーマリンク設定が「基本」になっているとREST APIが動作しない。また、セキュリティプラグインが/wp-json/へのアクセスを制限しているケースもある。.htaccessのリライトルールが破損している場合も404になるため、パーマリンク設定の再保存でリフレッシュするのが初手として有効だ。

この記事のポイント

  • サブフォルダ環境でプラグインのAPIが404になるのは、URLにサブフォルダが含まれない不完全なパスが原因
  • 問題のプラグインを最新版に更新し、パーマリンク設定を再保存するのが解決の基本手順
  • rest_url() の戻り値とwp-config.phpの設定を確認し、WordPress本体のURL認識が正しいか検証する
  • 全プラグインの無効化で競合を切り分け、キャッシュやセキュリティ系プラグインの干渉を疑う
Gravity Forms PDFで合計金額が倍になる原因と修正方法

Gravity Forms PDFで合計金額が倍になる原因と修正方法

Gravity Forms で作成したフォームから PDF を出力するプラグイン「PDF Invoices for Gravity Forms」を使っていて、テンプレート内で get_total() メソッドを複数回呼び出すと合計金額が呼び出し回数に応じて倍々に膨らんでしまう現象は、静的変数 self::$total が各呼び出しのたびに加算され続ける設計になっているのが原因だ。直すにはヘルパークラスを子テーマから拡張し、get_total() の内部で毎回リセットして再計算させる変更を加える。

合計金額が倍になる現象はどのようなときに起こるのか

合計金額が倍になる現象はどのようなときに起こるのか

たとえば請求書のテンプレートに「小計」と「総合計」を別々の位置に表示したい場合、PDF_Invoices_For_GravityForms_Helpers::get_total() を2回呼ぶことになる。ところがイベント参加登録や商品注文フォームなどで実際にこの処理を通すと、2回目の呼び出し時には1回目に加算された値にさらに同じ計算が上乗せされ、本来 10,000 円のところが 20,000 円になるといった不具合が起きる。

なぜ get_total() を複数回呼ぶと値が積み上がるのか

なぜ get_total() を複数回呼ぶと値が積み上がるのか

問題の根本は class-pcafe-gfpi-helpers.php ファイル内の get_total() メソッドにある。このメソッドは静的変数 self::$total を使い、内部で次のように加算している。

public static function get_total(){
    self::$total += self::get_subtotal();
    self::$total += self::$shipping;
    return self::$total;
}

静的変数はリクエストの間ずっと値を保持するため、同じ処理中に get_total() が呼ばれるたびに前回の合計に小計と送料が足されていく。2回呼べば「小計 + 送料」が2倍になり、3回なら3倍になる。通常、こうした合計取得メソッドは毎回ゼロから計算し直すべきであり、内部で継ぎ足す構造は意図したものでない可能性が高い。

Before(問題のある状態)
1回目呼び出し: 小計=10,000 + 送料=500 → total=10,500
変数 self::$total が 10,500 を保持したまま
2回目呼び出し: 10,500 + 10,000 + 500 → total=21,000
After(修正後のあるべき動作)
1回目呼び出し: 小計=10,000 + 送料=500 → total=10,500
2回目呼び出し: 変数をリセット後 再計算 → total=10,500
静的変数が保持され加算される問題  毎回リセットして再計算する修正後

上の図のように、2回目で合計が倍になる。特に「小計」「消費税」「総合計」など複数の金額を PDF テンプレートに配置する場合にこの問題が顕在化しやすい。

get_total() 修正の基本的な考え方

get_total() 修正の基本的な考え方

プラグイン本体のファイルを直接編集してしまうと、アップデートのたびに修正が上書きされて消える。そのため子テーマの functions.php を使い、プラグインのヘルパークラスを拡張した独自クラスを用意する方法をとる。拡張クラスでは get_total() メソッドをオーバーライドし、計算前に self::$total を強制的に 0 にリセットしてから小計と送料を加算する。

子テーマでヘルパークラスを拡張して修正する手順

子テーマでヘルパークラスを拡張して修正する手順

独自ヘルパークラスを作成する

まず子テーマの functions.php に、プラグインのヘルパークラスを継承したクラスを定義する。子テーマがない場合は、Code Snippets プラグインを使うか、wp-content/themes/(現在のテーマ)/functions.php に追記する形でもよい。コードは以下のようになる。

class Custom_GFPI_Helpers extends PDF_Invoices_For_GravityForms_Helpers {

    public static function get_total() {
        self::$total = 0; // 計算前に必ずリセットする
        self::$total += self::get_subtotal();
        self::$total += self::$shipping;
        return self::$total;
    }
}

テンプレート内でカスタムクラスを呼び出す

拡張クラスを作っただけでは既存のテンプレートには反映されない。PDF テンプレート内で PDF_Invoices_For_GravityForms_Helpers::get_total() を呼んでいる箇所を、先ほど定義した Custom_GFPI_Helpers::get_total() に置き換える。

テンプレートファイルは多くの場合 wp-content/uploads/pdf-invoices-for-gravity-forms/templates/ 以下にカスタムテンプレートとして配置されている。該当の .php ファイルを開き、以下のように書き換える。

<?php
// 修正前
// echo PDF_Invoices_For_GravityForms_Helpers::get_total();

// 修正後
echo Custom_GFPI_Helpers::get_total();
?>

これでテンプレート内のどの場所から呼び出しても、毎回リセット後に計算が走るため合計が積み上がることはなくなる。

変更後にキャッシュと動作を確認する

変更を加えたあとは、必ず PDF を生成し直して合計金額が正しいか確認する。Gravity Forms のエントリーから「PDFを表示」ボタンで実際の請求書を開き、同じ合計が要求された位置すべてに正しく表示されているかをチェックする。サイトでキャッシュプラグインを使っている場合は、キャッシュを全削除してから確認すると確実だ。

STEP 1 子テーマの functions.php にカスタムクラスを定義する
STEP 2 PDF テンプレート内の呼び出しを Custom_GFPI_Helpers に変更する
STEP 3 キャッシュを削除し、PDF を生成し直して合計金額を確認する

よくある質問

プラグイン本体のファイルを直接修正してもよいか

推奨しない。プラグインがアップデートされるたびに修正が上書きされ、その都度同じ変更を加えなければならなくなる。子テーマや Code Snippets を使う方法なら、アップデートに影響されず継続的に動作する。

他の金額表示(税額や値引き額)も倍増している場合の対処は

同じヘルパークラス内で定義されている get_tax()get_discount() にも同様の静的変数の加算構造がある可能性が高い。それらのメソッドも同じ要領でカスタムクラス内にオーバーライドし、内部で該当の静的変数をリセットする処理を加えるとよい。

子テーマを使っていない場合でも対応できるか

子テーマがない場合は Code Snippets プラグインが便利だ。スニペットとしてクラス定義を追加すれば、テーマに依存せず同じ修正を適用できる。テンプレートの書き換えは手動で行う必要があるが、クラスの読み込み自体はスニペット経由で問題なく動作する。

修正後に PDF が真っ白になる場合の確認点は

クラス名やメソッド名のスペルミス、オートローダーがカスタムクラスを見つけられていないケースが考えられる。まず PHP のエラーログを確認し、クラスが見つからないという趣旨の致命的エラーが出ていないか調べる。出ている場合はクラス定義の記述ミスか、定義のタイミングが早すぎる可能性があるため、init フックなどで定義を遅らせると改善することがある。

この記事のポイント

  • get_total() の多重呼び出しで合計が倍増するのは、静的変数 self::$total が加算され続ける設計のため
  • プラグイン本体を直接修正せず、子テーマの functions.php でカスタムクラスを定義する
  • カスタムクラス内で get_total() をオーバーライドし、計算前に self::$total = 0; でリセットする
  • PDF テンプレート側の呼び出しをカスタムクラスに差し替え、キャッシュ削除後に動作確認する
  • 同様の構造を持つ get_tax()get_discount() も併せて修正を検討する
WordPress 7.0.1でクラシックエディタ保存できない時の原因と直し方

WordPress 7.0.1でクラシックエディタ保存できない時の原因と直し方

WordPress 7.0.1 更新後にクラシックエディタや WPBakery などのページビルダーで投稿や固定ページを保存できない、下書きが消えるといった症状は、PHP 8.4 との互換性問題が原因だ。PHP バージョンを 8.3 以下に切り替えればこの問題は解消する。

クラシックエディタで保存できずリダイレクトされる現象の正体

クラシックエディタで保存できずリダイレクトされる現象の正体

WordPress 7.0.1 に更新した直後から、クラシックエディタプラグインを有効化していると「公開」「下書き保存」をクリックしても保存されず、投稿一覧にリダイレクトされてしまう。保存したはずの記事や固定ページは一覧からも消え、下書きにも残らない。

さらにややこしいのは、ブロックエディタ(Gutenberg)では問題なく保存できるという点だ。クラシックエディタのプラグインを無効化せずとも、ブロックエディタ側で開いて操作すれば保存は成功する。このため一見すると「特定のプラグインだけが壊れている」ように見えるが、実際にはクラシックエディタ系や WPBakery など旧来の編集画面に依存するツール全般で同じ症状が出る。

この現象はプラグイン側の不具合ではなく、WordPress コアが動作する PHP のバージョンに起因する。特に PHP 8.4 環境で顕在化しやすい。

なぜ PHP 8.4 でクラシックエディタが動作しなくなるのか

なぜ PHP 8.4 でクラシックエディタが動作しなくなるのか

根本原因は PHP 8.4 で廃止または挙動が変更された関数や構文が、クラシックエディタの編集画面や保存処理の中で使われていることにある。古いエディタ画面は WordPress コアの一部として動作するが、その内部処理が新しい PHP の厳格な型チェックや廃止予定の警告(Deprecated)に引っかかり、画面遷移やデータ保存に失敗する。

たとえば、PHP 8.4 では暗黙の nullable 型宣言が非推奨になり、引数のデフォルト値や型宣言の扱いが厳密化された。WordPress の管理画面まわりには長い歴史を持つコードが多く、こうした細かな PHP の変更に対してすべてのプラグインやテーマが追随できているわけではない。

ブロックエディタが正常に動作するのは、ブロックエディタの保存処理が REST API を経由し、比較的新しいコードベースで実装されているため、PHP 8.4 の影響を受けにくいからだ。

PHP バージョンを 8.3 に切り替えて問題を解消する

PHP バージョンを 8.3 に切り替えて問題を解消する

現時点で最も確実な対処法は、サーバーの PHP バージョンを 8.3 にダウングレードすることだ。PHP 8.4 はリリースされたばかりで、WordPress エコシステム全体の完全な互換性が確保されるまでは安定動作が見込める 8.3 を使うほうが無難である。

PHP 8.4
クラシックエディタ保存不可 → 一覧にリダイレクト → 記事消失
STEP 1 サーバー管理画面から PHP 設定を開く
STEP 2 PHP 8.3 を選択して適用する
PHP 8.3
クラシックエディタ正常保存・下書きも残る

多くのレンタルサーバーではコントロールパネル(cPanel や独自管理画面)から簡単に PHP バージョンを切り替えられる。

サーバー管理画面での具体的な操作

cPanel を使っている場合は「PHP の選択」または「MultiPHP Manager」といったメニューを探す。対象ドメインを選択し、ドロップダウンメニューから「PHP 8.3」を選んで保存するだけだ。変更は数分以内に反映される。

独自の管理画面を提供しているサーバーでも、多くの場合「PHP 設定」「PHP バージョン管理」といった項目がある。もし見つからなければサーバー運営会社のサポートに「PHP バージョンを 8.3 に変更したい」と伝えれば対応してくれるケースが多い。

変更前に現在の PHP バージョンを確認する

WordPress 管理画面の「ツール」→「サイトヘルス」→「情報」タブを開き、「サーバー」セクションを見ると現在の PHP バージョンが表示されている。ここで 8.4 以上であれば今回の問題に該当する可能性が高い。

PHP 8.3 への切り替えでも直らない場合の追加確認

PHP 8.3 への切り替えでも直らない場合の追加確認

ごくまれに、PHP バージョンを下げても問題が続くことがある。そんなときは次の3点を順に確かめる。

ブラウザキャッシュと WordPress キャッシュのクリア

PHP の変更後にブラウザのキャッシュが残っていると、古い JavaScript や CSS で画面が正しく動作しないことがある。ブラウザのキャッシュを削除するか、シークレットウィンドウで管理画面を開き直す。また、WordPress 側でキャッシュプラグインを使っている場合はそのキャッシュもすべて削除する。

管理画面で JavaScript エラーが出ていないか調べる

ブラウザの開発者ツール(F12 キー)を開き、「コンソール」タブで赤いエラーが出ていないか確認する。保存ボタンを押した瞬間に何らかの JavaScript エラーが記録されていれば、それが原因の手がかりになる。

WordPress のデバッグモードでログを取得する

wp-config.php に以下のコードを追加してデバッグモードを有効にすると、保存時のエラーが wp-content/debug.log に記録される。

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

ログに「Deprecated」や「Fatal error」が記録されていれば、それが直接の原因を示している。ただし、大半のケースでは PHP 8.3 への切り替えだけで問題が解消するため、ログを調べるのはレアケースの最終手段と考えてよい。

よくある質問

PHP 8.3 に戻すとセキュリティ面で問題はないか

PHP 8.3 は現在もアクティブサポートが継続しており、セキュリティ修正は提供され続けている。WordPress 公式の推奨バージョンでもあるため、本番環境で使っても安全だ。無理に最新の 8.4 に上げるよりも、安定した 8.3 で運用するほうが結果的にリスクが低い。

PHP 8.3 に変更したのにクラシックエディタがまだ使えない

PHP の変更がサーバーに完全に反映されるまで数分かかることがある。まずは数分待ってから再度試す。それでも改善しない場合は、一度プラグインを無効化して再度有効化してみる。また、前述のキャッシュクリアも忘れずに行う。

WPBakery や他のページビルダーでも同じ症状が出るのか

出る。クラシックエディタだけでなく、WPBakery をはじめとする旧型の編集画面を使うページビルダー全般が PHP 8.4 の影響を受ける。これらもブロックエディタと異なり、内部の保存処理が古いコードに依存しているためだ。

PHP バージョンを自由に変更できないサーバーではどうすればいいか

サーバー管理画面に PHP バージョンの変更オプションがない場合は、サーバー運営会社のサポートに連絡して「PHP 8.3 への切り替えを依頼したい」と伝える。ほとんどの会社は対応してくれる。もし変更ができないと言われた場合は、PHP 8.4 の環境でも動作するように WordPress のアップデートを待つか、ブロックエディタに一時的に切り替えて運用するしかない。

この記事のポイント

  • WordPress 7.0.1 でクラシックエディタ保存不可になる原因は PHP 8.4 の互換性問題
  • PHP バージョンを 8.3 に下げると問題は即座に解消する
  • ブロックエディタは PHP 8.4 でも正常に動作するため一時的な回避策になる
  • 変更後はブラウザキャッシュと WordPress キャッシュを忘れずにクリアする
  • PHP 8.3 は公式推奨でありセキュリティ面でも安全に運用できる
データベース接続確立エラーの原因と復旧手順

データベース接続確立エラーの原因と復旧手順

「データベース接続確立エラー」でサイトがダウンした場合、まずはサーバー会社に連絡してデータベースサーバーの稼働状況を確認し、wp-config.php の接続情報を照合するのが最短の復旧手順だ。自分でできる対処は限られているため、慌てずに切り分けを進める。

なぜ「データベース接続確立エラー」が突然発生するのか

なぜ「データベース接続確立エラー」が突然発生するのか

このエラーは WordPress がデータベースに接続できないときに表示される。日本語環境では「データベース接続確立エラー」というメッセージが画面に表示され、サイト全体が表示できなくなる。原因は大きく4つに分けられる。

  • wp-config.php 内のデータベース名・ユーザー名・パスワード・ホスト名のいずれかが誤っている
  • データベースサーバー自体がダウンしている(サーバー障害・メンテナンス)
  • データベースサーバーは稼働しているが、負荷集中で応答不能になっている
  • データベースが破損している(テーブルクラッシュなど)

サイトを長期間触っていなかったのに突然エラーが出た場合は、サーバー側で MySQL や MariaDB のバージョンアップ、パスワード変更、セキュリティ設定の変更が行われた可能性が高い。WordPress 側の設定ファイルは変わらないまま、サーバー側の接続条件だけが変わることで不一致が起きる。

Before(エラー発生中)
ブラウザに「データベース接続確立エラー」が表示される
wp-config.php とデータベースの認証情報が不一致、または DB サーバーが停止
After(復旧後)
サイトが正常表示される
正しい接続情報で WordPress がデータベースにアクセスできる状態
エラー状態  復旧後

エラーが出たらまず試す3つの切り分け

エラーが出たらまず試す3つの切り分け
STEP 1 サーバー会社にデータベースサーバーの稼働状況を確認する
STEP 2 wp-config.php の接続情報をサーバー管理画面の値と照合する
STEP 3 phpMyAdmin などでデータベースに直接接続できるか試す

サーバー会社にデータベースサーバーの状態を問い合わせる

最も確実で早いのが、利用しているサーバー会社のサポートに連絡することだ。データベースサーバーがダウンしていれば、自分で何をしても復旧しない。管理画面にログインできなくても、サーバー会社のコントロールパネル(cPanel や独自管理画面)にアクセスできれば、そこからデータベースの状態を確認できる場合もある。

特に共有サーバー(複数ユーザーで1台のサーバーを共有するプラン)では、他のユーザーの影響でデータベースサーバーに負荷がかかり、一時的に応答しなくなることがある。この場合もサーバー会社側で対処が必要になる。

wp-config.php の接続情報を確認する

FTP ソフトやサーバーのファイルマネージャーで WordPress のインストールディレクトリにある wp-config.php を開き、以下の4つの定数を確認する。

define( 'DB_NAME', 'database_name_here' );
define( 'DB_USER', 'username_here' );
define( 'DB_PASSWORD', 'password_here' );
define( 'DB_HOST', 'localhost' );

これらの値がサーバーのデータベース管理画面(phpMyAdmin やサーバー会社のコントロールパネル)で設定した値と完全に一致しているか確認する。サーバー会社がパスワードをリセットした場合や、セキュリティアップデートでホスト名が localhost から mysqlcluster2.example.com のような専用ホスト名に変更されるケースがある。

wp-config.php に一時的な確認コードを入れる

接続情報が正しいかどうかを切り分けるには、wp-config.php に以下のテストコードを追加する方法も有効だ。エラーメッセージの詳細が表示され、単なる認証エラーなのか、サーバー自体に到達できないのかが判別できる。

$link = mysqli_connect( DB_HOST, DB_USER, DB_PASSWORD, DB_NAME );
if ( ! $link ) {
    die( '接続失敗: ' . mysqli_connect_error() );
}
echo '接続成功';
die();

このコードを wp-config.php/* That's all, stop editing! Happy blogging. */ より上に追記し、サイトにアクセスする。「接続失敗」と表示されれば認証情報かサーバー到達性の問題、「接続成功」と表示されれば WordPress 本体やプラグイン側の別の要因が疑われる。確認が終わったら必ずこのコードを削除する。

phpMyAdmin からデータベースに直接接続する

サーバー会社のコントロールパネルから phpMyAdmin にアクセスし、該当のデータベースを開けるか確認する。開ければ、データベースサーバーは稼働しており、認証情報も正しいことがわかる。開けない場合は、ユーザー名・パスワードが誤っているか、そのユーザーにデータベースへのアクセス権限が付与されていない。

phpMyAdmin 自体が開けない、または読み込みに極端に時間がかかる場合は、データベースサーバーの高負荷やダウンが原因だ。この場合もサーバー会社への連絡が必要になる。

データベースの修復が必要なケース

データベースの修復が必要なケース

wp-config.php の情報が正しく、データベースサーバーも稼働しているのに接続エラーが出る場合、データベースのテーブルが破損している可能性がある。この修復は WordPress の自動修復機能で対応できる。

wp-config.php に以下の1行を追加する。

define( 'WP_ALLOW_REPAIR', true );

その後、ブラウザで https://あなたのサイトのURL/wp-admin/maint/repair.php にアクセスすると、データベース修復画面が表示される。「データベースを修復」または「データベースを修復して最適化」ボタンをクリックすれば修復が実行される。修復完了後は、セキュリティのために必ず追加した行を削除する。

管理画面にログインできない場合の対処

管理画面にログインできない場合の対処

「データベース接続確立エラー」が出ている間は、WordPress の管理画面(/wp-admin)にもアクセスできない。この状態では wp-config.php の確認や修正を WordPress の管理画面から行うことはできず、必ずサーバー側のファイルマネージャーか FTP ソフトを使う必要がある。

FTP の接続情報がわからない場合も、サーバー会社のサポートに連絡すれば、コントロールパネルへのログイン方法やファイルマネージャーの使い方を案内してもらえる。WordPress のログイン情報よりも先に、サーバーの管理画面にアクセスできる状態を確保することが復旧の第一歩だ。

再発を防ぐための日常的な対策

再発を防ぐための日常的な対策

データベース接続エラーは突然発生し、サイト全体が完全に停止するため、予防と早期発見の仕組みを整えておくことが重要だ。

  • サーバー会社のデータベース稼働状況を定期的にチェックする(障害通知メールの設定)
  • データベースの定期バックアップを自動化する(サーバー側のバックアップ機能やプラグインを利用)
  • wp-config.php のバックアップを手元に保管し、接続情報をメモしておく
  • サーバー会社のコントロールパネルと FTP のログイン情報を常に最新に保つ

特にレンタルサーバーの共有プランを利用している場合、サーバー会社がメンテナンスやセキュリティアップデートでデータベースの接続設定を変更することがある。変更の予告メールを見逃さないよう、サーバー会社からのメールは確実に受信できるアドレスに設定しておく。

よくある質問

データベース接続エラーと「重大なエラー」は別のものか

別のエラーだ。「データベース接続確立エラー」はデータベースとの通信そのものができない状態で、サイト全体が表示されない。「このサイトで重大なエラーが発生しました」は WordPress 本体やプラグインの PHP エラーで、管理画面にメールが届く場合もある。後者はデータベースに接続できていることが前提になる。

wp-config.php を修正したのに直らない場合はどうすればよいか

データベースサーバー自体が停止しているか、MySQL のサービスが落ちている可能性が高い。サーバー会社のコントロールパネルで MySQL の状態を確認し、停止していれば再起動を試みる。操作権限がない場合はサーバー会社に依頼する。

データベースのユーザー名やパスワードを忘れた場合はどうするか

サーバーのコントロールパネル(cPanel の「MySQL データベース」など)から確認または再設定できる。WordPress の管理画面からは確認できないため、必ずサーバー側の管理画面を使う。パスワードをリセットした場合は、wp-config.php の DB_PASSWORD も新しい値に更新する必要がある。

データベースの修復でデータが消えることはあるか

WP_ALLOW_REPAIR による修復は、破損したテーブルの構造を修復する機能で、保存されている投稿や設定データを削除することはない。ただし、修復作業の前には必ずデータベースのバックアップを取得しておくことが望ましい。

エラーが断続的に発生する場合の原因は何か

データベースサーバーの負荷が一時的に高まっているか、同時接続数の上限に達している可能性がある。アクセス集中時だけエラーが出る場合は、サーバースペックやプランの見直しを検討する。また、プラグインが非効率なデータベースクエリを大量に発行していないかも確認する。

この記事のポイント

  • データベース接続エラーは wp-config.php の誤りかサーバー側の障害が主因
  • エラー発生時は管理画面にログインできないため、FTP やサーバー管理画面で対応する
  • サーバー会社に連絡してデータベースサーバーの稼働状態を確認するのが最短の復旧手段
  • テーブル破損が疑われる場合は WP_ALLOW_REPAIR で修復を試みる
  • 日常的にバックアップと接続情報の控えを取っておくことで復旧時間を短縮できる
WordPress会員データが大量削除された時の原因と復旧手順

WordPress会員データが大量削除された時の原因と復旧手順

WordPress サイトで会員データが突然数千件単位で削除され、WP Activity Log に「Unknown user」として記録される事態は、データベースへの直接アクセスか管理者権限の乗っ取りによる攻撃の可能性が高い。即座にサイトをメンテナンスモードに切り替え、被害拡大を防ぎつつバックアップから復旧し、侵入経路を特定して再発を防ぐ必要がある。

なぜ突然会員データが大量削除されたのか

この事象の最大の特徴は、削除を実行したユーザーが「Unknown user」と表示される点にある。通常、WordPress の操作ログにはユーザー名かユーザー ID が記録されるが、ここに名前が出ないということは、wp_users テーブルを経由しない削除が行われていることを示している。考えられる原因は大きく3つに絞られる。

データベースへの直接操作

最も深刻なケースとして、攻撃者が SQL インジェクションや phpMyAdmin への不正アクセス、あるいはサーバーに仕込んだマルウェア経由でデータベースに直接 DELETE 文を実行している状況だ。この場合、WordPress のアクションやフィルターフックを一切通過しないため、WP Activity Log を含むどの監査プラグインもユーザーを特定できず「Unknown」となる。

管理者アカウントの乗っ取り

管理者権限を持つアカウントが乗っ取られ、攻撃者がそのアカウントで MemberPress の会員一括操作機能やデータベースクリーニング系プラグインを実行したケースだ。ただし、この場合は通常ユーザー名がログに残る。残っていないということは、攻撃者が操作後にユーザーごと削除したか、別の手段を使った可能性が高い。

REST API や XML-RPC の悪用

WordPress の REST API や XML-RPC に認証の弱点があると、外部から会員データの削除リクエストを送信される場合がある。特に、API 経由で直接データベース操作を行うカスタムエンドポイントがテーマやプラグインに存在すると、認証をすり抜けて大量削除が実行される危険がある。

大量削除が発生する3つの経路
A. データベース直接操作 SQL インジェクションやサーバー侵入により、DELETE 文を直接実行。WordPress のログを一切通過しないため「Unknown」になる。
B. 管理者アカウント乗っ取り 乗っ取った管理者で管理画面から一括削除。通常はユーザー名が残るが、アカウントごと削除された可能性もある。
C. REST API や XML-RPC の悪用 認証の脆弱性を突き、API 経由で削除リクエストを送信。プラグイン独自のエンドポイントに注意が必要。
最も深刻な経路  緊急調査が必要な経路

同時に多数のプラグイン更新が表示され、WordPress 7.0.1 への更新も同日にリリースされたという状況は、実際に重大な脆弱性が公表され、各開発者が一斉にパッチを配布している可能性を示唆している。更新が突如10件以上積み上がるのは、テーマやプラグインに含まれる共通ライブラリに脆弱性が見つかった場合によく見られるパターンだ。

攻撃を受けた直後にとるべき緊急対応の手順

攻撃を受けた直後にとるべき緊急対応の手順

被害の発覚から時間が経つほど、データ消失や情報流出の範囲は広がる。以下の手順を発見後30分以内に実行することで、二次被害を最小限に抑えられる。

STEP 1 サイトをメンテナンスモードに切り替え、外部からの全アクセスを遮断する
STEP 2 全プラグインとテーマを強制無効化し、攻撃者が仕込んだマルウェアの実行を止める
STEP 3 WP Activity Log をエクスポートし、攻撃元 IP と操作内容の全記録を保全する
STEP 4 直近の正常なバックアップからデータベースを復元する

メンテナンスモードでアクセスを遮断する

まず、攻撃が継続している可能性を想定し、サイト全体をメンテナンスモードに切り替える。管理画面にアクセスできる状態であれば、.maintenance ファイルを手動で作成する方法が最も確実だ。WordPress のルートディレクトリに .maintenance ファイルを配置し、以下の内容を記述すると、全訪問者にメンテナンス画面が表示される。

<?php
$upgrading = time();
?>

FTP やサーバーのファイルマネージャーでアクセスできない場合は、サーバー管理パネルから Web サーバー(Apache や Nginx)自体を停止するか、.htaccess に IP 制限をかけて特定の IP 以外をすべて拒否する方法も有効だ。

プラグインとテーマを強制的に無効化する

管理画面からプラグインを一括停止できない、あるいは管理画面自体が攻撃者にロックされている場合、FTP で /wp-content/plugins/ ディレクトリごとリネームする(例: plugins_backup)。これにより、WordPress は全プラグインを無効化した状態で起動する。同様に、/wp-content/themes/ から現在のテーマを除く全テーマを別ディレクトリに退避し、標準テーマ(Twenty Twenty-Five 等)のみを残す。

ログを保全して侵入経路を特定する

WP Activity Log のデータは攻撃者に消去される前にエクスポートする。CSV または JSON でダウンロードし、ローカルに保存する。このとき、サーバーのアクセスログ(access.log)とエラーログ(error.log)も必ず取得する。ログから得るべき情報は「攻撃元 IP」「削除が実行された正確な日時」「リクエスト URL(特に POST リクエスト)」「User-Agent」の4点だ。

「Unknown user」による削除操作が大量に記録されている場合、リクエスト URL が wp-admin/admin-ajax.phpwp-json/ を含んでいないかを重点的に確認する。これらが含まれていれば、AJAX や REST API 経由の攻撃である可能性が高い。

バックアップからの復旧とデータ整合性の確認

バックアップからの復旧とデータ整合性の確認

攻撃発生前の正常な状態がわかっているバックアップがあれば、それをリストアする。このケースのように2日前のバックアップが存在する場合、消失した会員データはその時点のものに戻るが、2日間に新規登録した会員や更新されたデータは失われるため、復旧後に差分を手動で補完する必要がある。

復旧の Before / After
Before(攻撃を受けた状態)
MemberPress 会員テーブルが数千件消失し「Unknown user」の削除ログのみが残っている。プラグイン更新が20件積み上がり、WP 7.0.1 が未適用。
After(復旧完了後)
バックアップから会員データをリストア。全プラグインと WP 本体を最新に更新し、不正ファイルを除去した状態でサイトを再公開。
攻撃直後の状態  復旧後の安全な状態

データベースをリストアする手順

バックアップが SQL ダンプファイル(.sql または .sql.gz)の場合、phpMyAdmin またはサーバーのコマンドラインからインポートする。WordPress のデータベース全体を置き換える場合は、まず現在の全テーブルを削除(DROP)してからインポートする。この操作は取り返しがつかないため、必ず現在のデータベースも別名でエクスポートしてから実行する。

# コマンドラインでのリストア例
mysql -u ユーザー名 -p データベース名 < backup.sql

リストア後、MemberPress の会員数が期待通りに戻っているか、会員のサブスクリプション状況や支払い履歴が正しく関連付けられているかを必ず確認する。特に、WooCommerce と連携している場合は wp_usermeta テーブルの整合性もチェックする必要がある。

再発を防ぐための恒久対策

再発を防ぐための恒久対策

復旧が完了したら、同じ攻撃を二度と受けないようにするための対策を即座に実施する。サーバー侵入を許した原因が残ったままだと、再度同じ経路から攻撃される危険が極めて高い。

全ファイルの改ざんチェックとマルウェアスキャン

WordPress のコアファイル、プラグイン、テーマのすべてについて、オリジナルの配布ファイルと比較して改ざんされていないかを確認する。WordPress の管理画面から「サイトヘルス」→「情報」→「ファイルの整合性」でコアファイルのチェックが可能だが、プラグインとテーマは手動かセキュリティプラグイン(Wordfence や Sucuri 等)を使ってスキャンする。特に、wp-content/uploads/ 内に .php ファイルが存在していないかを重点的に調べる。

管理者アカウントの総点検とパスワード再設定

すべての管理者アカウントについて、覚えのないユーザーが追加されていないか、権限が勝手に昇格されていないかを確認する。wp_users テーブルと wp_usermeta を直接確認し、不審な管理者を削除する。その上で、全管理者と編集者のパスワードを強制的にリセットし、可能であれば二要素認証(2FA)を導入する。WordPress 6.8 以降は標準でパスキー認証が利用できるため、セキュリティキーを使ったログインも有効な選択肢だ。

データベースのアクセス制限と監査の強化

データベースへの外部からの直接アクセスを遮断するため、phpMyAdmin などの管理ツールを公開ディレクトリに置かない、または IP 制限と HTTP 認証をかける。また、wp-config.php に以下の定数を追加して、WordPress のファイル編集機能を無効化しておくことで、管理画面を乗っ取られた場合でもテーマやプラグインのコードが書き換えられることを防げる。

define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true); // 必要な場合のみ

XML-RPC と REST API のアクセス制限

XML-RPC を使用していない場合は .htaccess でブロックするか、プラグインで完全に無効化する。REST API は多くのプラグインが依存しているため完全には無効化できないが、認証が必要なエンドポイントに対して適切な権限チェックが実装されているかを確認する。特に、MemberPress やカスタムプラグインが提供する REST API エンドポイントは、開発元のドキュメントでセキュリティ設定を再確認する。

よくある質問

WP Activity Log に「Unknown user」と表示されるのは必ずハッキングか

必ずしもそうとは限らないが、高い確率で不正アクセスが疑われる。プラグインのバグやデータベースの不整合でも発生しうるが、同時に大量のデータが削除されている場合は攻撃の可能性を第一に考えるべきだ。特に、管理者権限を持たない IP からの操作が記録されている場合はほぼ確実に侵入されている。

プラグインの更新が突然大量に表示されたのはなぜか

共通ライブラリやフレームワークに重大な脆弱性が見つかり、複数のプラグインが一斉にセキュリティアップデートをリリースした可能性が高い。WordPress 本体の緊急アップデートが同日にリリースされていることも、何らかの広範囲に影響する脆弱性が公表されたことを示唆している。これらの更新は速やかに適用すべきだ。

バックアップから復旧した後、消えたデータは完全に戻るのか

バックアップ取得時点のデータは戻るが、それ以降に追加・変更されたデータは復元されない。MemberPress の会員情報の場合、新規登録者やサブスクリプションの変更履歴が失われるため、復旧後に会員からの問い合わせをもとに手動で補完する必要がある。決済情報は決済代行サービス側に残っていることが多いため、そちらを参照して復元できる場合もある。

WP 7.0.1 への更新はすぐに適用すべきか

重大なセキュリティ修正を含むマイナーアップデートの場合、速やかな適用が推奨される。ただし、大量削除が発生した環境では、まずバックアップからの復旧と侵入経路の遮断を完了させてから更新を行う。更新前に全ファイルの改ざんチェックを済ませ、マルウェアが残っていない状態で適用するのが安全だ。

この記事のポイント

  • 「Unknown user」による大量削除はデータベース直接操作か管理者乗っ取りが原因の可能性が高い
  • 発見後は即座にメンテナンスモードでサイトを遮断し、プラグインを強制無効化して攻撃を止める
  • WP Activity Log とサーバーログを直ちにエクスポートし、攻撃元 IP と侵入経路を特定する
  • バックアップからデータベースをリストアし、復旧後に全ファイルの改ざんチェックとマルウェアスキャンを実施する
  • XML-RPC の無効化、REST API の権限確認、二要素認証の導入で再発を防ぐ