【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.5 | 2029 年 12 月 31 日 | 8.5.12 |
| 8.4 | 2028 年 12 月 31 日 | 8.4.27 |
| 8.3 | 2027 年 12 月 31 日 | 8.3.36 |
| 8.2 | 2026 年 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 段階がおすすめです。
- 今の環境を調べる:Web で動いている PHP のバージョン、使っている拡張機能、文字コード
- 検証環境で 7.4 に上げて直す:この記事の「7.0 で必要になる修正」
- 検証環境で 8.4・8.5 に上げて直す:7 系から 8 系への記事の内容
- 本番を 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 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 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 で動かし、古いコードを読ませます
# 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
PHPの「緊急」レベルの脆弱性、開発元が修正バージョン公開 - ITmedia NEWS


