先日、ある企業サイトの PHP バージョンアップを担当しました。サーバーは PHP 7.4、WordPress は 4.9 という、かなり年季の入った構成です。依頼は「PHP を上げて、あわせて WordPress とプラグインも最新にしてほしい」というものでした。
これだけ古いと、PHP を切り替えた瞬間に画面が真っ白……という展開も覚悟していたのですが、結果的には 致命的なエラーを一度も出さずに 作業を終えられました。テスト環境も作らず、本番サイトで直接作業しています。
この記事では、うまくいった理由と実際の手順、そして作業後に気づいた注意点をまとめます。PHP 切り替えの一般的な手順や、エラーが出たときの戻し方は「WordPressのPHPバージョンを安全に上げる手順」にまとめているので、あわせて読んでみてください。
今回の作業の概要
| 項目 | 作業前 | 作業後 |
|---|---|---|
| PHP | 7.4 | 8.3 |
| WordPress | 4.9 系 | 7 系の最新版 |
| テーマ | 制作会社による自作テーマ(お問い合わせフォームもテーマ内の PHP) | 2か所だけ修正 |
| サーバー | さくらのレンタルサーバ(FTP は使えるが SSH は使えない) | |
進めた順番は次のとおりです。ポイントは、PHP の切り替えを一番最後にした ことです。
- Claude にテーマを解析してもらい、修正版を先にアップロード(PHP 7.4 のまま)
- バックアップ(FTP でファイル一式、phpMyAdmin で DB)
- 全プラグインを停止して、WordPress 本体を 6 系の最終版へ(FTP で手動更新)
- WordPress を 7 系の最新版へ(管理画面から更新)
- プラグインを最新版にして、1つずつ有効化
- 最後に PHP を 8.3 へ切り替え
ポイント1:Claude にテーマを解析してもらい、修正ファイルを先に差し替えておく
PHP 8 で動かなくなる原因の多くは、テーマやプラグインに残っている古い書き方です。プラグインは最新版にすれば対応していることがほとんどですが、自作テーマは誰も直してくれません。とはいえ、テーマのファイルを 1 つずつ目で追って確認するのはかなり大変です。
そこで今回は、テーマのファイル一式を Claude(Anthropic の AI)に渡して解析してもらい、修正したファイルを WordPress のバージョンアップ前に差し替えておきました。具体的には、次のような流れです。
1. テーマフォルダを zip にして Claude に渡す
FTP でサーバーからテーマフォルダをダウンロードし、zip にして Claude のチャットに添付しました。頼んだのは「PHP 8.3 で動かなくなる箇所を洗い出して、PHP 7.4 と 8.3 の両方で動く修正版を作ってほしい」ということです。メールの送信先アドレスなど、外に出したくない値は伏せたままで問題ありませんでした。
2. PHP 8.3 で動かなくなる箇所を洗い出してもらう
Claude は、PHP_CodeSniffer の拡張ルール「PHPCompatibilityWP」を使って、テーマ内の PHP ファイル 17 個をすべてスキャンしてくれました。指定した PHP のバージョンで問題になる書き方を、ファイル名と行番号つきで一覧にしてくれるツールです。
phpcs -p --extensions=php --standard=PHPCompatibilityWP --runtime-set testVersion 7.4-8.3 ./テーマフォルダ
結果、直す必要があったのは、テーマ内に置かれたお問い合わせフォームの mail.php の 2 か所だけでした。どちらも get_magic_quotes_gpc() という、PHP 8.0 で削除された関数です。そのまま PHP 8 に切り替えていたら、フォームの確認画面でエラーになるところでした。
PHP のバージョン以外にも、WordPress を大きく上げるときに引っかかりそうな点をまとめて確認してもらいました。
- WordPress で廃止された関数を使っていないか:使っていませんでした。
- jQuery の更新の影響:WordPress 5.5 以降で jQuery 周りが大きく変わりましたが、このテーマは WordPress 付属の jQuery を使わず独自に読み込んでいたので、影響なしと判断できました。
- プラグインを止めてもテーマがエラーにならないか:パンくずやページ送りは
function_exists()で存在を確認してから呼ぶ書き方でした。これが分かっていたので、後の「全プラグイン停止」も安心してできました。
3. 新旧どちらの PHP でも動く修正版を作ってもらう
修正は、関数が存在するときだけ呼ぶ形にしてもらいました。
// 修正前
if(get_magic_quotes_gpc()) { $out = stripslashes($out); }
// 修正後
if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { $out = stripslashes($out); }
こうしておくと、PHP 7.4 では今までどおりに動き、PHP 8.3 では処理を飛ばすだけになります。あわせて、更新が止まっていた管理画面カスタマイズ用のプラグイン(WP Total Hacks)の代わりに、同じ設定を functions.php に書くコードも用意してもらいました。
修正した mail.php は、Claude が自分の作業環境の PHP 8.3 でフォームを実際に動かし、確認画面が表示されること、管理者宛てと自動返信の 2 通のメールが送信されることまで確かめてくれました。元のファイルでは確認画面でエラーになることも確認できています。
4. WordPress のバージョンアップ前に差し替える
受け取った修正版の mail.php と functions.php は、WordPress 本体を上げる前、PHP も 7.4 のままの段階で FTP で上書きしました。どちらの PHP でも動く形なので、先に入れておいても今のサイトには影響がありません。表示とフォームの動きが変わらないことを確認してから、次の作業に進みました。
これで、PHP を切り替える日にあわててファイルを差し替える必要がなくなります。切り替え後に何か起きても「テーマのせいではない」と切り分けられるのも安心材料でした。
なお、Claude の確認はあくまで手元の環境でのものなので、本番で PHP を切り替えたあとは、実際にフォームを送信してメールが届くことを自分でも確認しました。
ポイント2:Basic 認証の内側で、本番を直接作業する
本来なら、テスト環境(ステージング)を作って同じ手順を一度通してから本番に臨むのが理想です。ただ今回は、サイトがリニューアル公開前で、すでに Basic 認証で閉じられていました。一般の人には見えないので、作業中に表示が崩れても外部への影響はありません。
そこで、テスト環境は作らず本番で直接作業することにしました。環境を作ってファイルと DB を複製し、終わったら本番に反映する、という手間がまるごと不要になるので、作業時間はかなり短くなります。
もちろん、何も考えずに本番を触るわけではありません。次の条件をそろえたうえでの判断です。
- いつでも戻せる:ファイルと DB のバックアップを取ってから始める。PHP はコントロールパネルから数分で元に戻せる
- 一度に 1 つだけ変える:WordPress 本体、プラグイン、PHP を別々のステップに分け、そのたびに確認する
- 危ないところは先に潰しておく:テーマの修正は事前に済ませておく(ポイント1)
- 作業中は更新を止めてもらう:お客様に、作業期間中は記事を更新しないようお願いしておく
エラーの記録は、wp-config.php でデバッグログを有効にし、画面には出さずにファイルへ書き出すようにしました。各ステップのあとで wp-content/debug.log を開き、Fatal error がないかを確認します。
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
phpMyAdmin から DB をダウンロードする方法
SSH が使えないサーバーでは、DB のバックアップは phpMyAdmin から取るのが手軽です。さくらのレンタルサーバでの手順は次のとおりです。
- サーバーのコントロールパネルで「データベース」を開き、対象 DB の「管理ツール ログイン」から phpMyAdmin に入る。ユーザー名とパスワードは
wp-config.phpのDB_USER・DB_PASSWORD - 左の一覧から、
wp-config.phpのDB_NAMEと同じ名前の DB をクリックする。画面上部に DB 名が表示され、wp_postsなどのテーブル一覧が出ればOK - 上部の「エクスポート」タブを開き、「詳細 - 可能なオプションをすべて表示」を選ぶ
- 出力は「出力をファイルに保存する」、圧縮は「gzip 形式」、フォーマットは「SQL」にする
- 「DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT / TRIGGER コマンドを追加する」にチェックを入れる
- 一番下の「実行」でダウンロードする
つまずきやすいのは手順 2 です。ログイン直後の画面はサーバー全体のトップで、DB が選ばれていません。この状態でエクスポートを押すと、サーバー単位のエクスポート画面になってしまいます。
DROP TABLE のオプションを付けておくと、復元のときに既存のテーブルを自動で置き換えてくれるので、戻す作業が楽になります。gzip にするのは、phpMyAdmin でインポートできるファイルサイズに上限があるためです。ダウンロードしたら、ファイル名に「日付+どの時点か」(例:DB名_20261030_作業前.sql.gz)を付けておくと、あとで迷いません。今回は「作業前」「WordPress 更新後」「PHP 切り替え前」と、区切りごとに取りました。
全プラグインを停止してから WordPress を上げる
WordPress 本体を大きく上げるときは、先にプラグインをすべて停止 しておきます。古いプラグインが新しい WordPress の上でエラーを出し、管理画面に入れなくなるのを防ぐためです。停止しても設定は DB に残るので消えません。
手順
- 管理画面の「プラグイン」で、どれが有効だったかをスクリーンショットで残してから、全選択して「停止」
- 日本語版の WordPress(6 系の最終版)の zip をダウンロードして解凍する
- FTP で
wp-admin・wp-includesをwp-admin_new・wp-includes_newという名前でアップロードし、ファイル数が手元と一致するか確認する - サーバー上で旧フォルダを
_oldに、_newを正式名にリネームする。切り替えは数秒で終わるので、壊れた状態の時間を最小にできる - 直下のファイル(
wp-login.php、wp-settings.phpなど)を上書きする。wp-contentとwp-config.phpは触らない /wp-admin/upgrade.phpを開いて、データベースを更新する- Classic Editor を入れて、投稿画面を今までと同じにしておく
- 7 系の最新版へは、管理画面の「更新」から上げる(WordPress.org につながらない場合は、同じく FTP で)
- プラグインを最新版にして、1 つずつ有効化しながら表示と debug.log を確認する
4.9 から 5.x を経由せずに 6 系へ上げたのは、PHP 7.4 が途中のどの版でも動作要件を満たしていて、DB の更新処理も途中の版の分までまとめて実行されるためです。PHP を途中で上げる必要がないなら、刻みすぎない方が作業時間を短くできます。
本体を上げた直後、debug.log は作られなくなりました。PHP 7.4 に対応していなかった 4.9 が出していた大量の警告が、6 系で出なくなったためです。プラグインを止めていたので、本体の更新でエラーになる要素がほとんどなかったことになります。なお、プラグインを止めている間はパンくずやページ送りが消えますが、テーマ側が存在確認をしてから呼ぶ書き方なのは事前の解析で分かっていたので、エラーにはなりません。
PHP 8.2 以上を必要とするプラグイン(今回は WP-PageNavi)は、停止したまま PHP を切り替え、その直後に更新・有効化しました。最後に PHP を 8.3 に切り替え、フォームの送信とメール到着まで確認して完了です。
気をつけたいこと:All in One SEO の大型アップデートで設定が変わる
今回、一番注意が必要だったのが All in One SEO(AIOSEO)です。3 系から 4 系以降への更新は、ほぼ作り直しに近い大型アップデートです。旧設定は自動で移行されますが、移行されない設定や、初期値に戻ってしまう設定がありました。
作業前に主要ページの <title> と meta description、robots の設定を記録しておき、更新後に照合したところ、次の差分が見つかりました。
- タイトルの区切り文字が「|」から「-」に変わっていた(全ページ)
- トップページの title の末尾に区切り文字が付き、meta description が空になっていた
- 記事の description が途中で切れているものがあった
- 日付アーカイブの noindex が外れていた
- 作業前は出していなかった OGP タグと XML サイトマップが出力されるようになった
どれも画面が崩れるような変化ではないので、見た目のチェックだけでは気づけません。放っておくと検索結果の表示が変わってしまいます。AIOSEO を使っているサイトを更新するときは、更新前に title・description・noindex の設定を記録しておき、更新後に照合する ことをおすすめします。新しく出力されるようになった機能(OGP やサイトマップ)は、出すかどうかをお客様と決めておきましょう。また、更新後にセットアップウィザードが出ても、実行すると今の設定が上書きされることがあるので、閉じておくのが無難です。
まとめ
- テーマのファイル一式を Claude に解析してもらい、新旧どちらの PHP でも動く修正版を WordPress のバージョンアップ前に入れておくと、PHP 切り替え当日にエラーが出ない
- Basic 認証で閉じたサイトなら、バックアップと戻し方を用意したうえで、テスト環境を作らず本番で作業でき、作業時間を短縮できる
- DB は phpMyAdmin から、gzip・DROP TABLE 付きで、区切りごとにダウンロードしておく
- WordPress 本体は全プラグインを停止してから上げ、プラグインは最新版にして 1 つずつ戻す。PHP の切り替えは最後
- All in One SEO の大型アップデートでは、一部の設定が変わる・リセットされることがあるので、更新前後で照合する
古いサイトほど「何が起きるか分からない」のが怖いところですが、事前に中身を見ておけば、怖さのほとんどは作業前に片づけられます。同じような案件を抱えている方の参考になればうれしいです。
