このサイトのドメインには、WordPress のサイトや自作の道具など、サブドメインのサイトがいくつもあります。古い PHP のままだったので、PHP 8.3 に上げました。
エックスサーバーの PHP のバージョンは、ドメインごとの設定です。本体だけを上げるつもりでも、サブドメインのサイトも全部いっしょに 8.3 になります。そこで、切り替える前に、全部のサイトが 8.3 で動くかを確かめました。そのやり方と、途中でつまずいたところをまとめます。
確かめの流れ
| 順 | やること | 分かること |
|---|---|---|
| 1 | 作業環境(PHP 8.3)でサイトを開く | WordPress のサイトが動くか・ログに何が出るか |
| 2 | サーバーの上で php8.3 -l をまとめて流す | PHP 8.3 では文法が通らないファイル |
| 3 | PHP 8 でなくなった関数を探す | 文法は通っても、開いたときに止まるファイル |
| 4 | サーバーパネルで切り替える | — |
| 5 | 全部のサイトを開いて確かめる | 本番で止まっていないか |
1. 作業環境で動かしてみる
WordPress のサイトは、本番を作業環境(XAMPP・PHP 8.3)に複製してあったので、まず開いてみました。
止まるようなエラーはなく、ログに出たのは次のような「Deprecated」(そのうち使えなくなるというお知らせ)だけでした。動きは止まりません。
PHP Deprecated: Creation of dynamic property My_Meta_Box::$description is deprecated in …/class-my-meta-box.php on line 110
これは、クラスに書いていないプロパティを後から足すと、PHP 8.2 から出るお知らせです。PHP 8.3 でも動きは変わりません。
2. サーバーの上で php8.3 -l をまとめて流す
作業環境がない自作の道具などは、ファイルを落とさずに、サーバーの上で確かめました。エックスサーバーでは、SSH で入るとバージョンごとの PHP(/usr/bin/php8.3 など)が使えます。
php -l は、ファイルを動かさずに、文法だけを確かめます。なので、本番のファイルに使っても安全です。
cd /home/(ユーザー名)/(ドメイン)/public_html
for d in sub1 sub2 sub3; do
echo "== $d"
find $d.example.com -name "*.php" -not -path "*/vendor/*" -print0 \
| xargs -0 -r -n1 /usr/bin/php8.3 -l 2>&1 | grep -v "^No syntax errors"
done
何も問題がなければ、== サイト名 の行だけが並びます。
ファイルが多いと止まって見える
1 つのサイトに PHP のファイルが 1 万 1 千あり、1 つずつ確かめると、止まったように見えるほど時間がかかりました。画像やキャッシュのフォルダを外し、-P8 で 8 つずつ並べて流すと、すぐ終わりました。
エラーが 1 つ出ると、そこで止まる
別のサイトで、次のエラーが出たところで、残りのファイルを確かめずに終わっていました。
PHP Fatal error: Array and string offset access syntax with curly braces is no longer supported in …/WavFile.php on line 1569 xargs: /usr/bin/php8.3: 終了ステータス 255。中止しています
xargs は、呼んだコマンドが 255 で終わると、そこで中止します。php -l は文法のエラーのときに 255 を返すので、最初のエラーで止まってしまいます。
sh -c '…; true' で包んで、いつも 0 で終わるようにすると、最後まで調べられます。
find sub1.example.com -name "*.php" -not -path "*/vendor/*" -not -path "*/uploads/*" -not -path "*/cache/*" -print0 \ | xargs -0 -r -n1 -P8 sh -c '/usr/bin/php8.3 -l "$0" 2>&1 | grep -v "^No syntax errors"; true' echo "おわり"
見つかったエラー
| 出たもの | 意味 | 直し方 |
|---|---|---|
| Array and string offset access syntax with curly braces is no longer supported(Fatal) | $str{0} のように、波かっこで 1 文字を取り出す書き方。PHP 8.0 から使えない |
$str[0] に直す |
| Using ${var} in strings is deprecated(Deprecated) | 文字列の中の "${var}" の書き方。PHP 8.2 から非推奨 |
"{$var}" に直す。今は動く |
// PHP 7.4 で非推奨、PHP 8.0 からエラー
$c = $str{0};
// 角かっこに直す
$c = $str[0];
Fatal が出たのは、古いお問い合わせのフォームの画像認証(音声で読み上げる部分)で、もう使っていないサイトでした。なので、そのまま切り替えました。
3. PHP 8 でなくなった関数を探す
php -l は文法しか見ません。PHP 8 でなくなった関数(each()・create_function()・mysql_connect() など)を使っていても文法は通り、そのページを開いたときに初めて止まります。そこで、関数の名前で探しました。
grep -rlE "\beach\(|create_function\(|\bmysql_(connect|query)\(|\bereg(i)?\(|\bsplit\(" --include=*.php .
すると、WordPress 本体やプラグインのファイルが 30 以上出てきました。中を見ると、ほとんどが PHP のファイルの中に書いた JavaScript の .each( や .split( でした。PHP の関数ではないので、見まちがいです。
前が . や -> の呼び出しを外し、WordPress 本体とプラグイン(作業環境で動くのを確かめたもの)も外して、探し直しました。
grep -rnE "(^|[^.>$A-Za-z0-9_])(each|create_function|mysql_connect|mysql_query|ereg|eregi|split)\(" --include=*.php . \
| grep -vE "/vendor/|/wp-admin/|/wp-includes/|/wp-content/plugins/" | cut -c1-160
残ったのは mysql_connect と mysql_query の 2 行だけで、どちらもコメント(/* … */)の中でした。今は PDO で DB につないでいるので、問題ありません。
出てきた行は、コメントの中か・本当に呼ばれているかを、ファイルを開いて確かめるのが確実です。
気をつけたこと:知らないスクリプトを外から開かない
途中で、公開フォルダに古いスクリプトが残っているのを見つけました。外から開けるかを確かめようと、ヘッダーだけを取る形(curl -I・HEAD)で開きました。
すると、その中の 1 つが LINE に通知を送るスクリプトで、試しのメッセージが届いてしまいました。HEAD でも、PHP は最後まで動きます。中身が分からないスクリプトは、開く前に手元のコピーで中身を読むようにしています。
使っていないスクリプトだったので、バックアップを取ってから消しました。
4. 切り替える
エックスサーバーのサーバーパネルの「PHP Ver.切替」で、ドメインの PHP を 8.3 にして「変更」を押します。反映までは数分かかることがあります。止まるものが出ても、同じ画面で元のバージョンに戻せます。
5. 全部のサイトを開いて確かめる
切り替えた直後と、15 分ほどたってから、本体とサブドメインのトップと主なページを開いて確かめました。
for u in https://example.com/ https://sub1.example.com/ https://sub2.example.com/; do
printf "%s %s\n" "$(curl -s -o /tmp/c.html -w '%{http_code}' "$u?nc=$RANDOM")" "$u"
grep -oiE ".{0,80}(fatal error|parse error|重大なエラー).{0,80}" /tmp/c.html | head -1
done
「重大なエラー」の文字が 1 つ引っかかりましたが、中を見ると「サイトに重大なエラーがありました」という記事のタイトルでした。文字で探したときは、出てきた所を必ず見ます。
結果
| サイト | 数 | PHP 8.3 での結果 |
|---|---|---|
| WordPress のサイト | 5 | 作業環境で動いた。本番も 200(Deprecated のお知らせだけ) |
| 自作の道具・見本のサイト | 5 | 文法も、なくなった関数も問題なし |
| 使っていないサイト | 2 | Fatal が 1 つ(波かっこの書き方)。使っていないのでそのまま |
| 転送だけのサイト | 1 | 前と同じ 301 |
切り替えたあとも、全部のサイトが今までどおり開いています。


