エックスサーバーで PHP を 8.3 に上げる前に、サブドメインのサイトまでまとめて確かめる:php8.3 -l の一括チェックと、なくなった関数の探し方

広告WordPress・PHP を学べる本

Amazonのアソシエイトとして、WordPress functions.phpは適格販売により収入を得ています。

このサイトのドメインには、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 は、ファイルを動かさずに、文法だけを確かめます。なので、本番のファイルに使っても安全です。

SSH で実行
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 で終わるようにすると、最後まで調べられます。

SSH で実行(止まらない形)
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

切り替えたあとも、全部のサイトが今までどおり開いています。

参考

関連機能

  1. WordPress WP_CACHE constant is not present in wp-config.php WP-Optimize プラグインで発生

  2. WordPress 予約投稿の失敗を解決 Scheduled Post Trigger

  3. WordPress 「現在メンテナンス中のため、しばらくの間ご利用いただけません。」画面を解除する方法

サイドバー

よく使うカスタマイズ

最近の記事

Profile

PAGE TOP