2026.10.23

【2026年版】PHP 5系から8系へのバージョンアップ手順|緊急の脆弱性対策と移行の進め方

はじめに

この記事では、PHP 5 系(5.3〜5.6 など)で動いているシステムを PHP 8 系(8.4・8.5)に上げる進め方をまとめました。PHP 7 系からの場合はPHP 7 系から 8 系へのバージョンアップ手順をどうぞ。

まず:2026 年 10 月の PHP の「緊急」の脆弱性

2026 年 10 月 21 日(日本時間では 21 日深夜)、PHP の開発チームが深刻度「緊急」の脆弱性 2 件の修正版を公開しました。ネットでは「php2shell」とも呼ばれています。

  • CVE-2026-109618:メモリ不足のときの処理の不具合で、メモリが壊れる
  • CVE-2026-109619:あるリクエストで使い終わったメモリの情報が残り、同じプロセスが処理する次のリクエストで使われてしまう
  • どちらも深刻度は CVSS v4.0 で 9.2。ログインなしで、外からサーバー上のプログラムを動かされるおそれがあります
  • 影響するのは、Web のリクエストを処理しているすべての PHP です(PHP-FPM、Apache の mod_php、php-cgi、FrankenPHP、LiteSpeed など)。特に mod_php は、アプリのコードが動く前に攻撃できることが確かめられていて、いちばん危険とされています

公開の前日には情報の一部が漏れ、国内でも多くの Web サービスやレンタルサーバーが、念のためサービスを止めたりメンテナンスをしたりする騒ぎになりました。

古い PHP には、公式の修正版が出ない

バージョンセキュリティサポートの期限10 月の脆弱性の修正版
8.52029 年 12 月 31 日8.5.12
8.42028 年 12 月 31 日8.4.27
8.32027 年 12 月 31 日8.3.36
8.22026 年 12 月 31 日(あと 2 か月ほど)8.2.35
7.4・8.0・8.1終了公式の修正版なし(自分でビルドする人向けの最小限の修正だけ)
7.3 以前・5 系終了なし

修正版が出たのは 8.2〜8.5 だけです。7.4・8.0・8.1 には、自分で PHP をビルドする人向けに最小限の修正のソースが特別に公開されましたが、ふつうの更新としては出ていません。PHP 5 系と 7.3 以前には何もありません。

設定で攻撃の経路を減らす方法(php.ini の session.upload_progress.enabled = 0 など)も案内されていますが、公式は「完全な回避策はなく、アップデートだけが安全な選択肢」としています。

セキュリティ会社の調べでは、ネットから見える PHP のサーバーの約 7 割が、公式の修正が出ないバージョンで動いているとされています。古い PHP のシステムを持っている人にとって、バージョンアップを先延ばしにできる状況ではなくなりました。

今から上げるなら 8.4 か 8.5

8.2 は 2026 年 12 月 31 日でサポートが終わり、8.3 もすでにセキュリティの修正だけの期間に入っています。今から上げるなら、8.4(2028 年末まで)か 8.5(2029 年末まで)を目標にしましょう。使っているフレームワークや CMS、ライブラリが 8.5 に対応していれば 8.5、まだなら 8.4 が無難です。

5 系から 8 系は「作り直しに近い」こともある

PHP 5 系の最後(5.6)が出たのは 2014 年で、8 系までの間に 7.0 と 8.0 という 2 回の大きな変更があります。特に 7.0 では、データベースに接続する mysql_ 関数が丸ごと削除されたので、DB を使うシステムはほぼ必ず書き直しが必要です。

まずは、どれくらいの規模になりそうかを見積もりましょう。

  • フレームワークを使っているか:古いフレームワークは、それ自体が PHP 8 で動かないことが多く、フレームワークの版上げ=作り直しになることも
  • mysql_ 関数を使っている箇所の数:多いほど大変
  • テストの仕組みがあるか:無ければ、画面を一つひとつ手で確かめることになる
  • 文字コード:EUC-JP や Shift_JIS で作られていないか(後で説明)

規模が大きすぎる場合は、PHP を上げるのではなく、新しく作り直す・既製のサービスに置き換えることも選択肢です。

進め方:7.4 を足場にして 2 段階で上げる

5 系から 8 系へ一気に上げると、7.0 の変更と 8.0 の変更が同時に出て、原因を切り分けにくくなります。検証環境で、まず 7.4 で動くように直し、次に 8.4・8.5 に上げる 2 段階がおすすめです。

  1. 今の環境を調べる:Web で動いている PHP のバージョン、使っている拡張機能、文字コード
  2. 検証環境で 7.4 に上げて直す:この記事の「7.0 で必要になる修正」
  3. 検証環境で 8.4・8.5 に上げて直す:7 系から 8 系への記事の内容
  4. 本番を 8.4・8.5 に切り替える

7.4 はすでにサポートが終わっていて、10 月の脆弱性の修正版も出ていません。7.4 は検証環境で直すための足場として使うだけにして、本番は 7.4 で止めずに 8 系まで上げましょう。

7.0 で必要になる修正

mysql_ 関数 → PDO か mysqli

いちばん大きな修正です。mysql_connect()・mysql_query() などは 7.0 で削除されました。PDO に書き換えるのがおすすめです。書き換えるついでに、SQL に値を直接つなげている箇所はプリペアドステートメントにしましょう(SQL インジェクション対策)。

PHP
// PHP 5 系(7.0 で動かない)
$link = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('shop', $link);
$result = mysql_query("SELECT * FROM items WHERE id = " . $_GET['id']);
while ($row = mysql_fetch_assoc($result)) { /* ... */ }

// PDO に書き換える
$pdo = new PDO('mysql:host=localhost;dbname=shop;charset=utf8mb4', 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$stmt = $pdo->prepare('SELECT * FROM items WHERE id = ?');
$stmt->execute([$_GET['id']]);
foreach ($stmt as $row) { /* ... */ }

ereg 関数 → preg 関数

PHP
// PHP 5 系
if (ereg('^[0-9]+$', $zip)) { /* ... */ }
$parts = split(',', $csv);

// preg 関数に(正規表現の前後に / などの区切り文字が要る)
if (preg_match('/^[0-9]+$/', $zip)) { /* ... */ }
$parts = explode(',', $csv); // 正規表現が要らなければ explode で

eregi() は preg_match() に i を付けて、ereg_replace() は preg_replace() に書き換えます。

そのほか 7.0 で削除・変更されたもの

  • preg_replace() の /e 修飾子 → preg_replace_callback() に
  • <% %>(ASP 形式)や <script language="php"> のタグ → <?php ?> に
  • $HTTP_RAW_POST_DATA → file_get_contents('php://input') に
  • 多くの「止まるエラー」が、Error という例外に変わった(try / catch で受けられる)
  • $$foo['bar'] のような可変変数の解釈の順番が変わった
  • int・string・bool などが予約語になり、クラス名に使えなくなった

7.1〜7.4 で変わるもの

  • 7.1:引数が足りないと例外(ArgumentCountError)。mcrypt が非推奨(7.2 で削除)→ openssl に
  • 7.2:each()・create_function() が非推奨(8.0 で削除)。数えられない値への count() で警告
  • 7.4:$str{0} の添字の書き方や、マジッククォートの関数が非推奨(8.0 で削除)

これらは 8.0 で削除されるので、7.4 の段階で直しておくと 8 系に上げるときが楽になります。

日本語のシステムで注意したい文字コード

古い日本語のシステムは、EUC-JP や Shift_JIS で作られていることがあります。PHP の文字コードの設定も変わっているので、文字化けに注意しましょう。

  • mbstring.internal_encoding などの設定は 5.6 から非推奨で、default_charset を使います
  • mbstring.func_overload(strlen() などを自動で mb_strlen() に置き換える設定)は 8.0 で削除されました。使っていた場合は、mb_ 関数に書き換える必要があります
  • DB の接続でも文字コードを指定します(PDO なら DSN に charset=utf8mb4)

この機会に UTF-8 へ移すのも手ですが、データの変換が必要になるので、PHP のバージョンアップとは別の作業として計画しましょう。

使えるツール

  • php -l:新しい PHP で構文エラーを見つける(まず全ファイルにかける)
  • PHPCompatibility:指定したバージョンで問題になる書き方を一覧にする。5 系から 8 系までの変更をまとめて調べられます
  • Rector:決まった書き換えを自動でする。Rector は新しい PHP で動かし、古いコードを読ませます
bash
# PHPCompatibility で、7.4 と 8.4 で問題になる箇所を一覧にする
composer config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
composer require --dev phpcompatibility/php-compatibility:"^10.0.0@dev"
vendor/bin/phpcs -p . --standard=PHPCompatibility --runtime-set testVersion 7.4 --ignore=vendor/
vendor/bin/phpcs -p . --standard=PHPCompatibility --runtime-set testVersion 8.4 --ignore=vendor/

5 系から 7 系への移行では「php7cc」というツールもよく使われてきました(使い方はphp7ccのすすめ)。ただし php7cc は今はもう更新されていないので、新しく始めるなら PHPCompatibility を中心にするのがおすすめです。ツールの使い方の詳細は7 系から 8 系への記事にまとめています。

8 系に上げるとき

7.4 で動くようになったら、8.4・8.5 に上げます。8.0 の「文字列と数値の比較」の変更や、8.1 以降の「null の受け渡し」「動的プロパティ」など、7 系から上げるときと同じところでつまずきます。くわしくはPHP 7 系から 8 系へのバージョンアップ手順をどうぞ。

まとめ

  • 2026 年 10 月の「緊急」の脆弱性は、PHP 5 系には修正が一切出ない
  • 上げる先は 8.4 か 8.5。検証環境で 7.4 を足場に 2 段階で上げる(本番は 7.4 で止めない)
  • いちばん大きいのは mysql_ 関数の削除。PDO とプリペアドステートメントに書き換える
  • 古い日本語のシステムは文字コード(EUC-JP・Shift_JIS、mbstring.func_overload)に注意
  • 規模が大きすぎるなら、作り直しや置き換えも選択肢

参考

PHP の公式サイトの告知と移行ガイド、ツールの公式ドキュメント、国内の報道(2026 年 10 月 23 日時点)をもとにまとめています。

Security advisory: Critical remote code execution vulnerabilities - php.net

Supported Versions - php.net

PHPの「緊急」レベルの脆弱性、開発元が修正バージョン公開 - ITmedia NEWS

PHP 5.6.x から PHP 7.0.x への移行 - PHP マニュアル

PHPCompatibility - GitHub

TFT
soflan102本の記事