【2026年版】PHP 7系から8系へのバージョンアップ手順|緊急の脆弱性対策と非互換の直し方
はじめに
この記事では、PHP 7 系(7.0〜7.4)で動いているシステムを PHP 8 系(8.4・8.5)に上げる手順をまとめました。PHP 5 系からの場合はPHP 5 系から 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 が無難です。
バージョンアップの流れ
- 今の環境を調べる:Web で動いている PHP のバージョン、フレームワーク・CMS・ライブラリのバージョン
- 新しい PHP の検証環境を作る:本番と同じ OS・Web サーバーで、PHP だけ 8.4 か 8.5 にする
- ツールで問題の箇所を洗い出す:構文チェック、PHPCompatibility、Rector
- 直して、画面を一通り動かして確かめる:エラーログを見ながら
- 本番を切り替える:切り戻しの手順を用意してから
Web で動いている PHP のバージョンを確かめる
サーバーで php -v と打って出るのは、コマンドライン(CLI)用の PHP です。Web で動いている PHP とは別のバージョンのことがあるので、Web 側でも確かめます。
<?php
// 確かめたらすぐ消すこと(バージョンを外に見せたままにしない)
echo PHP_VERSION, ' / ', PHP_SAPI;PHP_SAPI が apache2handler なら mod_php、fpm-fcgi なら PHP-FPM です。mod_php なら、上げるついでに PHP-FPM への切り替えも検討しましょう。
ツールで問題の箇所を洗い出す
1. 構文チェック(php -l)
まず、新しい PHP で全ファイルの構文を確かめます。Docker があれば、サーバーに入れなくても試せます。
# PHP 8.4 で、vendor 以外の .php を全部チェックし、エラーだけ表示する
docker run --rm -v "$PWD":/app -w /app php:8.4-cli \
sh -c "find . -name '*.php' -not -path './vendor/*' -print0 | xargs -0 -n1 php -l | grep -v '^No syntax errors'"2. PHPCompatibility(非互換の箇所を一覧にする)
PHP_CodeSniffer のルール集「PHPCompatibility」で、指定したバージョンで問題になる書き方を一覧にできます。コードは書き換えません。
composer config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
composer require --dev phpcompatibility/php-compatibility:"^10.0.0@dev"
# 8.4 で問題になる箇所を一覧にする
vendor/bin/phpcs -p . --standard=PHPCompatibility --runtime-set testVersion 8.4 --ignore=vendor/3. Rector(自動で書き換える)
Rector は、決まった書き換えを自動でしてくれるツールです。いきなり書き換えず、--dry-run で差分を見てから適用します。Git などで、元に戻せる状態にしてから使いましょう。
<?php
use Rector\Config\RectorConfig;
return RectorConfig::configure()
->withPaths([__DIR__ . '/src'])
// composer.json の "require": {"php": "^8.4"} を読んで、そのバージョン向けの書き換えをする
->withPhpSets();composer require rector/rector --dev
vendor/bin/rector process --dry-run # 差分を見るだけ
vendor/bin/rector process # 書き換える一度に全部を変えると確かめきれないので、公式も「少しずつ進める」ことをすすめています。
PHP 8.0 でつまずきやすいところ
7 系から上げるとき、いちばん変更が大きいのが 8.0 です。
文字列と数値の比較が変わった
数値と、数字ではない文字列を == で比べたときの結果が変わりました。エラーにならずに結果だけ変わるので、いちばん見つけにくい変更です。
var_dump(0 == "a"); // 7 系: true → 8 系: false
var_dump("1" == "01"); // true(数字どうしは今までどおり)
var_dump(0 == ""); // 7 系: true → 8 系: false== で値を比べている箇所、特に switch や in_array()(第 3 引数なし)を見直しましょう。=== で型まで比べるのが安全です。
警告だったものがエラー(例外)になった
- 関数に間違った型の引数を渡すと、警告ではなく TypeError になります
- 数えられない値に
count()を使うと TypeError(7.2 から警告が出ていたもの) - 定義されていない定数を使うとエラー(7 系では文字列として扱われ、警告だけ)
@で、止まるエラーを隠せなくなりました- 既定の
error_reportingがE_ALLになり、今まで隠れていた注意が表示されるようになります
削除された関数
each()→foreachに書き換えcreate_function()→ 無名関数function () { ... }に書き換えget_magic_quotes_gpc()など、マジッククォートの関数- 文字列や配列の
{}での添字アクセス($str{0})→$str[0]
PHP 4 形式のコンストラクタ
クラスと同じ名前のメソッドは、コンストラクタとして呼ばれなくなりました。__construct() に名前を変えます。
8.1〜8.5 でつまずきやすいところ
8.1:組み込み関数に null を渡すと非推奨の警告
$name = $_GET['name'] ?? null;
echo strlen($name); // 8.1 から非推奨の警告
echo strlen($name ?? ''); // null のときは空文字にするフォームの値や DB の NULL をそのまま trim()・strlen()・htmlspecialchars() などに渡している箇所が大量に見つかることがあります。
8.1:mysqli のエラーが例外になった
mysqli の既定が「エラーのとき例外を投げる」に変わりました。if (!$result) でエラーを見ていたコードは、例外で止まるようになります。try / catch で受けるように直しましょう。
8.2:動的プロパティが非推奨
class User {}
$u = new User();
$u->age = 20; // 宣言していないプロパティに代入すると、8.2 から非推奨の警告
// 直し方: プロパティを宣言する
class User {
public int $age;
}すぐに直せないクラスには #[\AllowDynamicProperties] を付けると、警告を止められます。
8.2:そのほか
utf8_encode()・utf8_decode()が非推奨 →mb_convert_encoding()に- 文字列の中の
"${var}"の書き方が非推奨 →"{$var}"に
8.4:引数の「暗黙の null 許容」が非推奨
function find(User $user = null) {} // 8.4 から非推奨
function find(?User $user = null) {} // ? を付ける8.4 では、IMAP・OCI8・pspell の拡張が PHP 本体から外れました(PECL から入れる)。使っている場合は注意しましょう。
8.5:そのほか
- コマンドをバッククォートで囲んで実行する書き方が非推奨 →
shell_exec()に (integer)・(boolean)・(double)の型キャストが非推奨 →(int)・(bool)・(float)に- PDO の MySQL 用の定数(
PDO::MYSQL_ATTR_INIT_COMMANDなど)が非推奨 →Pdo\Mysql::ATTR_INIT_COMMANDに
非推奨は、今すぐ動かなくなるわけではありません。ただ、次のメジャーバージョンで削除される予定なので、余裕があるうちに直しておきましょう。
本番を切り替えるときの注意
- エラーログを必ず見る:画面に出ない警告や非推奨の注意も、ログには出ます。切り替えてからしばらくは毎日見ましょう
- フレームワーク・CMS・ライブラリを先に上げる:古いバージョンのままだと、新しい PHP で動かないことがあります。
composer.jsonの PHP のバージョンも上げます - php.ini を見直す:古い設定(削除された設定)が残っていないか。セッションやアップロードの上限も確かめる
- 切り戻しの手順を用意する:古い PHP にすぐ戻せるようにしてから切り替える。ただし、古い PHP に戻すのは、修正版の無い脆弱性を抱えたままに戻ることでもあります
まとめ
- 2026 年 10 月の「緊急」の脆弱性は、PHP 7 系には公式の修正版が出ない
- 上げる先は 8.4 か 8.5(8.2 は 2026 年末でサポート終了)
- ツールは php -l・PHPCompatibility・Rector。Rector は
--dry-runで差分を見てから - 8.0 の文字列と数値の比較はエラーにならずに結果が変わるので要注意
- 8.1 以降は、null の受け渡し・mysqli の例外・動的プロパティが多く見つかる
参考
PHP の公式サイトの告知と移行ガイド、ツールの公式ドキュメント、国内の報道(2026 年 10 月 23 日時点)をもとにまとめています。
Security advisory: Critical remote code execution vulnerabilities - php.net
PHPの「緊急」レベルの脆弱性、開発元が修正バージョン公開 - ITmedia NEWS


