PHP アップグレード特集
藍色の照明に照らされたサーバールームの通路

Special Feature — PHP Upgrade after PHP2Shell

サーバーの PHP は更新した。
次は、古いコードを 8.4 へ

PHP2Shell(CVE-2026-109618 / 109619)の対応で 8.x の修正版を入れたあと、
5.3〜8.1 で書かれたソースコードを移すための、起点バージョン別ガイドです。

11 系列起点 5.3〜8.1(全 393 パッチ版)
4 版移行先 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12
213 項目削除・非推奨・挙動変更
推奨の移行先は 8.4.27(次点 8.5.12)

🤝 対応中の同僚と共有してくださいPHP2Shell 対応でコード改修を分担している人に、このページをそのまま渡せます。

𝕏 X で共有 Facebook LINE はてなブックマーク LinkedIn Threads Bluesky Teams メール

このページを入口にしてください

2026年10月21日、PHP の開発チームは認証なしの遠隔コード実行につながる脆弱性 2 件を直した 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 を公開しました。まずやるべきはサーバー側の更新で、これはこのページの前半に書きます。後半と各論ページは、その次の段階、つまり「8.1 以前で動いているコードを、サポートの続く版で動くように直す」作業のためのものです。

起点のバージョン(いま動いている PHP)ごとにページを分け、移行先までに入った削除・非推奨・挙動変更を 1 項目ずつ並べました。お使いのバージョンが分かれば、該当ページだけ読めば足ります。

🔖 起点ごとのページにここから飛べます

あなたのPHPコードが動いているバージョンをクリックすれば作業内容がわかります。。作業の途中で「どの項目まで見たか」を確かめに戻れるよう、このトップページを保存しておいてください。

Windows Ctrl+DMac ⌘+Dスマホ 共有 → ブックマーク
🔍 自分のバージョンから探す

チームで分担するときは、このURLを共有してください。

今回の脆弱性 PHP2Shell とは

PHP2Shell は、CVE-2026-109618 と CVE-2026-109619 の 2 件をまとめた呼び名です。どちらも CVSS v4.0 で 9.2 と評価され、PHP 公式の勧告は「認証なしの遠隔コード実行を許し得る」と書いています。アプリケーションのコードではなく、PHP 本体がリクエストを処理する部分の不具合なので、自分のコードに問題がなくても影響を受けます。

経緯

日時出来事
10/20(火)PHP セキュリティチームが「10月21日 14:00 UTC(日本時間 23:00)に、CVSS v4.0 9.2 の致命的な脆弱性 2 件を直すセキュリティリリースを出す」と予告。詳細が公になったり悪用が確認されたりした場合は前倒しする、とも書いた
10/21(水)8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 を公開し、セキュリティ勧告を掲載。CERT-EU の記録では公開は 13:30 UTC(日本時間 22:30)で、予告より 30 分早い
10/21(水)同じ勧告で、EOL の 7.4 / 8.0 / 8.1 向けに最小限のソースバックポートを GitHub のブランチで提供。ディストリビューションと LTS ベンダーは事前にパッチを受け取っていた

出典: PHP News Archive 2026(10/20 予告・10/21 勧告とリリース告知)、CERT-EU Security Advisory 2026-018

2 つの脆弱性の仕組み

CVE-2026-109618(メモリ不足時の破損による RCE、GHSA-w8hw-w9fx-j79w)。PHP は memory_limit を超えたリクエストを longjmp() で途中から打ち切ります。フォームからのファイルアップロードを解析している最中のように、リクエストの内部データがまだ途中までしか初期化されていない時点で打ち切られると、後片付けの処理がその不完全なデータを正しいものとして扱い、初期化されていないメモリを解放してしまう。そのメモリには、攻撃者が送り込んだデータが前の確保から残っている可能性があります。

CVE-2026-109619(古いグローバル状態による RCE、GHSA-6wmf-4rv5-p3rp)。Fatal error などのあと、リクエストに属する内部状態が、裏のメモリを解放された後も残ることがあります。同じワーカーが次に処理するリクエストが、通常の初期化で上書きされる前にその古い状態を使ってしまう、という不具合です。

CVE-2026-109618 メモリ不足時の破損 リクエスト受信 ファイルアップロード等 memory_limit 超過 データは初期化の途中 longjmp で中断 処理が途中で打ち切り 後片付けが誤認 未初期化メモリを解放 CVE-2026-109619 古いグローバル状態 リクエスト A 同じワーカーで処理 Fatal error など メモリは解放される 内部状態だけ残る 解放済みを指したまま 次のリクエスト B 初期化前に古い状態を使用

図1: 上は「途中で打ち切られたデータを、後片付けが正しいものとして扱う」流れ。下は「前のリクエストの状態を、次のリクエストが使ってしまう」流れ(PHP 公式勧告と CERT-EU の説明から作図)。

影響を受ける構成

公式勧告が対象に挙げているのは、Web リクエストを処理するすべての PHP です。CLI で動かすバッチだけの環境は列挙に入っていませんが、同じマシンで Web も動いているなら対象になります。

実行形態(SAPI)対象補足
Apache + mod_php対象・最も危険公式は危険度が最も高いと評価。アプリケーションのコードが動く前に、認証なしの 1 リクエストで攻撃を起こせる実証がある
PHP-FPM(nginx / Apache など)対象公式の列挙に含まれる。nginx と組み合わせた構成もここに入る
php-cgi対象公式の列挙に含まれる
FrankenPHP / LiteSpeed対象公式の列挙に含まれる

影響を受ける版は、8.5 系の 8.5.12 未満、8.4 系の 8.4.27 未満、8.3 系の 8.3.36 未満、8.2 系の 8.2.35 未満です(CERT-EU の整理)。8.1 以前は PHP プロジェクトの更新対象外の EOL 版で、CERT-EU も影響を受ける製品として EOL 系列を挙げています。

見落としやすいのが、PHP を中に組み込んだ製品です。CERT-EU は「多くの商用・オープンソース製品が PHP をバックエンドに使っている」と注意を促し、オランダの NCSC-NL が公開している一覧リポジトリ NCSC-NL/php2shell で、自社で使っている機器やソフトが該当するか確かめるよう勧めています。サーバーに PHP を入れた覚えがなくても、管理画面が PHP で動くアプライアンスは珍しくありません。

悪用の状況(2026年10月23日時点)

ここは情報源によって書き方が違うため、断定はしません。CERT-EU は「最初の概念実証コード(PoC)が出回り始めており、攻撃者がすでに悪用している可能性がある」と書いています[1]。カナダのサイバーセキュリティセンターは 10月21日の時点で「PoC は入手可能だが、実際の悪用は確認されていない。状況はすぐ変わり得る」としています[2]。どちらにしても、インターネットから届く場所にある古い PHP は、更新を後回しにできる状態ではありません。

サーバー側で実施すべき更新

コードの改修より先に、まずサーバーです。公式の告知は「完全な緩和策は無く、更新だけが安全な選択」と明記しています。いま動いている系列ごとに、やることは次のとおりです。

いまの系列更新先・対処状況
8.58.5.12 へパッチ更新(コード改修なし)修正版あり
8.48.4.27 へパッチ更新(コード改修なし)修正版あり
8.38.3.36 へパッチ更新(コード改修なし)修正版あり
8.28.2.35 へパッチ更新。ただし 2026-12-31 でセキュリティサポートが終わるので、続けて 8.4 以降への移行を計画する修正版あり
8.1 / 8.0 / 7.4ディストリビューションや LTS ベンダーのバックポート版を使う。ソースからビルドしている場合は、公式が出した最小限のソースバックポート(8.1 / 8.0 / 7.4)を使う応急処置のみ
7.3 以前(5.x を含む)公式のバックポートは 7.4 / 8.0 / 8.1 向けだけ。ベンダーの延長サポートが無ければ、サポートされる系列へ移すことが唯一の根本対策。移行が終わるまでは下の緩和策と、公開範囲の縮小で守る修正なし

入手経路ごとの注意

  • ディストリビューションのパッケージ: 公式によると、Linux ディストリビューションと LTS ベンダーには事前にパッチが渡っています。パッケージ名の版番号はディストリビューション独自の付け方なので、ベンダーのセキュリティ告知で CVE 番号が修正済みかを確かめてください。
  • remi リポジトリ(rpms.remirepo.net): 公式告知は、公開当日に更新が出ないことを明記し、ディストリビューションのパッケージかソースビルドへ切り替えるよう勧めています。RHEL 系で remi を使っている環境は、パッケージが届いているかを個別に確認してください。
  • Docker イメージ: FROM php:8.4-fpm のような書き方でも、手元にキャッシュされた古いイメージから作り直すと更新されません。docker pull してから再ビルドし、コンテナの中で版を確かめます。

更新後の確認

パッケージを入れ替えただけでは、動いているプロセスは古いままです。CVE-2026-109619 は「同じワーカーが次に処理するリクエスト」で起きるので、全ワーカーの再起動まで済ませて初めて更新が効きます。コマンド名やサービス名はディストリビューションで違うので、下は例として読んでください。

# CLI の版(Web 側と別のバイナリのこともある)
php -v

# FPM の版(Debian / Ubuntu では php8.4-fpm のような名前)
php-fpm -v

# Apache に mod_php が読み込まれているか(php_module が出たら mod_php)
apachectl -M | grep -i php

# FPM を再起動して全ワーカーを入れ替える(サービス名は環境に合わせる)
sudo systemctl restart php-fpm

# Web 経由でも版を確かめる。確認後はこのファイルを必ず消す
echo '<?php echo PHP_VERSION;' | sudo tee /var/www/html/v.php
curl -s http://localhost/v.php ; sudo rm /var/www/html/v.php

すぐに更新できないときの緩和策

以下は公式勧告が挙げているものをそのまま並べたものです。公式は「特定の攻撃経路への露出を減らすだけで、安全にはならない」と明記しています。更新までのつなぎとして使ってください。

対象緩和策(公式の列挙)
CVE-2026-109618
  • memory_limit=-1 を、アプリが上書きできない形(FPM プールや Apache 設定の php_admin_value)で設定し、プール・ディレクトリ・アプリの設定が有限の値に戻していないか確かめる
  • post_max_size を低くする。アップロード不要なら 8M、必要なら 32M。upload_max_filesize はそれより小さく
  • Web サーバーやプロキシで、デコード後のリクエストサイズ、入力フィールド数、multipart のパート数、ヘッダー数、ネストの深さを制限する(Content-Length の無いリクエストも含めて)
  • コンテナや cgroup のメモリ制限を可用性の境界として使う。RLIMIT_AS や RLIMIT_DATA で代用しない(それ自体が脆弱な経路を引き起こし得る)
CVE-2026-109619
  • session.upload_progress.enabled=0 を php.ini か FPM プール・サーバー設定で設定し、全ワーカーを再起動する。ini_set() や .user.ini では効かない
  • PHP 8.5 では fatal_error_backtraces=0 にして全ワーカーを再起動する
  • リクエストごとに適用される無効・非推奨な設定で、初期化前に診断メッセージを出すものを取り除く。error_reporting・display_errors・@ で隠しても意味がない
  • 攻撃者が到達できる Fatal error と実行タイムアウト(コールバック、アップロードやインポート処理、後片付けの失敗を含む)を直す

CERT-EU はさらに、すぐ更新できないインターネット向けの資源は、修正を適用して確認できるまで隔離するよう勧めています。7.3 以前のように修正版が存在しない環境では、mod_php から PHP-FPM への切り替え、WAF、管理画面を社内からしか開けないようにする、といった公開範囲の縮小を組み合わせて、移行完了までの時間を稼ぐことになります。

サーバーは直った。次はコード

8.2〜8.5 のどれかを使っていた人は、パッチ版を上げるだけで今回の対応は終わります。問題は 8.1 以前で動いていたシステムです。バックポートで今回の穴をふさいでも、本家のサポートが終わった系列には次の脆弱性の修正が出ません。同じことがまた起きたとき、その都度ベンダー頼みになります。

では 8.2〜8.5 のどれへ移すか。ここで、よく聞かれる「8.2 / 8.3 / 8.4 / 8.5 の間で互換性は保たれているか」に答えておきます。

  • パッチ版の間(例: 8.2.0 → 8.2.35)は保たれています。 3 つ目の数字はバグ修正とセキュリティ修正だけで、後方互換性を壊す変更は原則入りません。例外はセキュリティ修正に伴う挙動変更で、7.3.23 / 7.4.11 の「Cookie 名を URL デコードしない」のような事例がごく稀にあります。
  • マイナー版の間(8.2 → 8.3 → 8.4 → 8.5)は保たれていません。 2 つ目の数字が変わるたびに、後方互換性のない変更と非推奨化が入ります。7.x から 8.0 のような大きな断絶ではなく、大半は Deprecated の通知(動作は続く)と限られた削除・挙動変更ですが、8.2 向けのコードが 8.5 で無修正のまま動く保証はありません。本特集のカタログでは、8.3 で 14 項目、8.4 で 16 項目、8.5 で 22 項目を数えています。

そのうえで、移行先は 8.4.27 を第一候補、新しい版を長く使いたいなら 8.5.12 とします。8.2.35 は 2026-12-31 でセキュリティサポートが終わるので、いまから移す先には選びません。8.3.36(2027-12-31 まで)は、8.4 で増える非推奨(暗黙の nullable 型など、Deprecated が大量に出るもの)を今回は踏みたくない場合の妥協点です。各論ページでは、移行先を切り替えると必要な項目だけが表示されるようにしてあります。

移行先公開日セキュリティサポート位置づけ
8.4.272026-10-212028-12-31 まで第一候補
8.5.122026-10-212029-12-31 まで最も長く使える。8.5 の非推奨 12 項目も一度に片付ける
8.3.362026-10-212027-12-31 まで8.4 の非推奨を後回しにしたい場合の妥協点
8.2.352026-10-212026-12-31 まで選ばない(あと約 2 か月)

サポート期限の出典: PHP Supported Versions、8.2 の EOL は 8.2.35 のリリース告知にも明記

あなたのバージョンから該当ページへ

php -v に出る番号をそのまま入れてください。同じ系列(2 つ目の数字まで同じ)なら、どのパッチ版から移しても必要な対応は同じなので、案内するページは系列ごとに 1 つです。

試す:

起点 × 移行先の項目数

セルの数字は、起点から移行先までに入った変更の数です(括弧内は 削除/非推奨/挙動変更)。数字を押すと、その移行先を選んだ状態で各論ページが開きます。

起点(系列の最終版)→ 8.2.35→ 8.3.36→ 8.4.27(推奨)→ 8.5.12
5.3.2916151/36/7417552/40/8319154/47/9021355/59/99
5.4.4514842/35/7116243/39/8017845/46/8720046/58/96
5.5.3814241/32/6915642/36/7817244/43/8519445/55/94
5.6.4013241/29/6214642/33/7116244/40/7818445/52/87
7.0.3310026/26/4811427/30/5713029/37/6415230/49/73
7.1.338620/25/4110021/29/5011623/36/5713824/48/66
7.2.347718/22/379119/26/4610721/33/5312922/45/62
7.3.336717/21/298118/25/389720/32/4511921/44/54
7.4.335415/15/246816/19/338418/26/4010619/38/49
8.0.30283/13/12424/17/21586/24/28807/36/37
8.1.34131/6/6272/10/15434/17/22655/29/31

経由するマイナー版と、越える山

起点の次のマイナー版から移行先までの各版で入った変更を、順に確認していくことになります。「山」は互換性を大きく壊した 7.0 と 8.0 のことです。

起点8.4.27 まで8.5.12 まで越える山
5.3.295.4〜8.4(13 版)5.4〜8.5(14 版)PHP 7.0・PHP 8.0
5.4.455.5〜8.4(12 版)5.5〜8.5(13 版)PHP 7.0・PHP 8.0
5.5.385.6〜8.4(11 版)5.6〜8.5(12 版)PHP 7.0・PHP 8.0
5.6.407.0〜8.4(10 版)7.0〜8.5(11 版)PHP 7.0・PHP 8.0
7.0.337.1〜8.4(9 版)7.1〜8.5(10 版)PHP 8.0
7.1.337.2〜8.4(8 版)7.2〜8.5(9 版)PHP 8.0
7.2.347.3〜8.4(7 版)7.3〜8.5(8 版)PHP 8.0
7.3.337.4〜8.4(6 版)7.4〜8.5(7 版)PHP 8.0
7.4.338.0〜8.4(5 版)8.0〜8.5(6 版)PHP 8.0
8.0.308.1〜8.4(4 版)8.1〜8.5(5 版)なし(Deprecated 中心)
8.1.348.2〜8.4(3 版)8.2〜8.5(4 版)なし(Deprecated 中心)

全パッチ版の対応表(393 版)

パッチ番号は各系列で x.y.0 から最終版まで連番で、欠番はありません。たとえば 7.3 系の最終は 7.3.33 なので、「7.3.44」というリリースは存在しません。サーバーの表示がそれ以外の番号なら、ディストリビューションが独自に付けた番号の可能性があります。

PHP 5.3.0〜8.1.34 の全パッチ版と、参照するページ(開く)
  • PHP 5.3 系(30 版)→ 5.3 系のページ:5.3.0 / 5.3.1 / 5.3.2 / 5.3.3 / 5.3.4 / 5.3.5 / 5.3.6 / 5.3.7 / 5.3.8 / 5.3.9 / 5.3.10 / 5.3.11 / 5.3.12 / 5.3.13 / 5.3.14 / 5.3.15 / 5.3.16 / 5.3.17 / 5.3.18 / 5.3.19 / 5.3.20 / 5.3.21 / 5.3.22 / 5.3.23 / 5.3.24 / 5.3.25 / 5.3.26 / 5.3.27 / 5.3.28 / 5.3.29
  • PHP 5.4 系(46 版)→ 5.4 系のページ:5.4.0 / 5.4.1 / 5.4.2 / 5.4.3 / 5.4.4 / 5.4.5 / 5.4.6 / 5.4.7 / 5.4.8 / 5.4.9 / 5.4.10 / 5.4.11 / 5.4.12 / 5.4.13 / 5.4.14 / 5.4.15 / 5.4.16 / 5.4.17 / 5.4.18 / 5.4.19 / 5.4.20 / 5.4.21 / 5.4.22 / 5.4.23 / 5.4.24 / 5.4.25 / 5.4.26 / 5.4.27 / 5.4.28 / 5.4.29 / 5.4.30 / 5.4.31 / 5.4.32 / 5.4.33 / 5.4.34 / 5.4.35 / 5.4.36 / 5.4.37 / 5.4.38 / 5.4.39 / 5.4.40 / 5.4.41 / 5.4.42 / 5.4.43 / 5.4.44 / 5.4.45
  • PHP 5.5 系(39 版)→ 5.5 系のページ:5.5.0 / 5.5.1 / 5.5.2 / 5.5.3 / 5.5.4 / 5.5.5 / 5.5.6 / 5.5.7 / 5.5.8 / 5.5.9 / 5.5.10 / 5.5.11 / 5.5.12 / 5.5.13 / 5.5.14 / 5.5.15 / 5.5.16 / 5.5.17 / 5.5.18 / 5.5.19 / 5.5.20 / 5.5.21 / 5.5.22 / 5.5.23 / 5.5.24 / 5.5.25 / 5.5.26 / 5.5.27 / 5.5.28 / 5.5.29 / 5.5.30 / 5.5.31 / 5.5.32 / 5.5.33 / 5.5.34 / 5.5.35 / 5.5.36 / 5.5.37 / 5.5.38
  • PHP 5.6 系(41 版)→ 5.6 系のページ:5.6.0 / 5.6.1 / 5.6.2 / 5.6.3 / 5.6.4 / 5.6.5 / 5.6.6 / 5.6.7 / 5.6.8 / 5.6.9 / 5.6.10 / 5.6.11 / 5.6.12 / 5.6.13 / 5.6.14 / 5.6.15 / 5.6.16 / 5.6.17 / 5.6.18 / 5.6.19 / 5.6.20 / 5.6.21 / 5.6.22 / 5.6.23 / 5.6.24 / 5.6.25 / 5.6.26 / 5.6.27 / 5.6.28 / 5.6.29 / 5.6.30 / 5.6.31 / 5.6.32 / 5.6.33 / 5.6.34 / 5.6.35 / 5.6.36 / 5.6.37 / 5.6.38 / 5.6.39 / 5.6.40
  • PHP 7.0 系(34 版)→ 7.0 系のページ:7.0.0 / 7.0.1 / 7.0.2 / 7.0.3 / 7.0.4 / 7.0.5 / 7.0.6 / 7.0.7 / 7.0.8 / 7.0.9 / 7.0.10 / 7.0.11 / 7.0.12 / 7.0.13 / 7.0.14 / 7.0.15 / 7.0.16 / 7.0.17 / 7.0.18 / 7.0.19 / 7.0.20 / 7.0.21 / 7.0.22 / 7.0.23 / 7.0.24 / 7.0.25 / 7.0.26 / 7.0.27 / 7.0.28 / 7.0.29 / 7.0.30 / 7.0.31 / 7.0.32 / 7.0.33
  • PHP 7.1 系(34 版)→ 7.1 系のページ:7.1.0 / 7.1.1 / 7.1.2 / 7.1.3 / 7.1.4 / 7.1.5 / 7.1.6 / 7.1.7 / 7.1.8 / 7.1.9 / 7.1.10 / 7.1.11 / 7.1.12 / 7.1.13 / 7.1.14 / 7.1.15 / 7.1.16 / 7.1.17 / 7.1.18 / 7.1.19 / 7.1.20 / 7.1.21 / 7.1.22 / 7.1.23 / 7.1.24 / 7.1.25 / 7.1.26 / 7.1.27 / 7.1.28 / 7.1.29 / 7.1.30 / 7.1.31 / 7.1.32 / 7.1.33
  • PHP 7.2 系(35 版)→ 7.2 系のページ:7.2.0 / 7.2.1 / 7.2.2 / 7.2.3 / 7.2.4 / 7.2.5 / 7.2.6 / 7.2.7 / 7.2.8 / 7.2.9 / 7.2.10 / 7.2.11 / 7.2.12 / 7.2.13 / 7.2.14 / 7.2.15 / 7.2.16 / 7.2.17 / 7.2.18 / 7.2.19 / 7.2.20 / 7.2.21 / 7.2.22 / 7.2.23 / 7.2.24 / 7.2.25 / 7.2.26 / 7.2.27 / 7.2.28 / 7.2.29 / 7.2.30 / 7.2.31 / 7.2.32 / 7.2.33 / 7.2.34
  • PHP 7.3 系(34 版)→ 7.3 系のページ:7.3.0 / 7.3.1 / 7.3.2 / 7.3.3 / 7.3.4 / 7.3.5 / 7.3.6 / 7.3.7 / 7.3.8 / 7.3.9 / 7.3.10 / 7.3.11 / 7.3.12 / 7.3.13 / 7.3.14 / 7.3.15 / 7.3.16 / 7.3.17 / 7.3.18 / 7.3.19 / 7.3.20 / 7.3.21 / 7.3.22 / 7.3.23 / 7.3.24 / 7.3.25 / 7.3.26 / 7.3.27 / 7.3.28 / 7.3.29 / 7.3.30 / 7.3.31 / 7.3.32 / 7.3.33
    注: 7.3.23 以降は Cookie 名を URL デコードしなくなった(bug #79699 のセキュリティ修正)。7.3.0〜7.3.22 から移す場合はこれも確認する。
  • PHP 7.4 系(34 版)→ 7.4 系のページ:7.4.0 / 7.4.1 / 7.4.2 / 7.4.3 / 7.4.4 / 7.4.5 / 7.4.6 / 7.4.7 / 7.4.8 / 7.4.9 / 7.4.10 / 7.4.11 / 7.4.12 / 7.4.13 / 7.4.14 / 7.4.15 / 7.4.16 / 7.4.17 / 7.4.18 / 7.4.19 / 7.4.20 / 7.4.21 / 7.4.22 / 7.4.23 / 7.4.24 / 7.4.25 / 7.4.26 / 7.4.27 / 7.4.28 / 7.4.29 / 7.4.30 / 7.4.31 / 7.4.32 / 7.4.33
    注: 7.4.11 以降は Cookie 名を URL デコードしなくなった(bug #79699 のセキュリティ修正)。7.4.0〜7.4.10 から移す場合はこれも確認する。
  • PHP 8.0 系(31 版)→ 8.0 系のページ:8.0.0 / 8.0.1 / 8.0.2 / 8.0.3 / 8.0.4 / 8.0.5 / 8.0.6 / 8.0.7 / 8.0.8 / 8.0.9 / 8.0.10 / 8.0.11 / 8.0.12 / 8.0.13 / 8.0.14 / 8.0.15 / 8.0.16 / 8.0.17 / 8.0.18 / 8.0.19 / 8.0.20 / 8.0.21 / 8.0.22 / 8.0.23 / 8.0.24 / 8.0.25 / 8.0.26 / 8.0.27 / 8.0.28 / 8.0.29 / 8.0.30
  • PHP 8.1 系(35 版)→ 8.1 系のページ:8.1.0 / 8.1.1 / 8.1.2 / 8.1.3 / 8.1.4 / 8.1.5 / 8.1.6 / 8.1.7 / 8.1.8 / 8.1.9 / 8.1.10 / 8.1.11 / 8.1.12 / 8.1.13 / 8.1.14 / 8.1.15 / 8.1.16 / 8.1.17 / 8.1.18 / 8.1.19 / 8.1.20 / 8.1.21 / 8.1.22 / 8.1.23 / 8.1.24 / 8.1.25 / 8.1.26 / 8.1.27 / 8.1.28 / 8.1.29 / 8.1.30 / 8.1.31 / 8.1.32 / 8.1.33 / 8.1.34

推奨する進め方(全起点共通)

どの起点からでも、順番はほぼ同じです。各論ページでは、これを起点ごとの事情に合わせて具体的に書いています。

  1. 暫定防御を固める。 8.1 以前には今回の脆弱性の正式な修正リリースがありません(7.4 / 8.0 / 8.1 はソースビルド向けの最小限のバックポートのみ、7.3 以前は公式の修正なし)。移行が終わるまで、WAF、mod_php から PHP-FPM への切り替え、公開範囲の縮小で守り、使えるならディストリビューションやホスティング事業者のバックポート版に替えておきます。
  2. 移行先を決める。 8.4 か 8.5。8.2 は数か月で EOL なので選びません。
  3. 機械的に洗い出す。 PHPCompatibility(--runtime-set testVersion 8.4)、PHPStan、Rector(withPhpSets() で 8.4 までの規則)で、削除された関数や構文を一覧にします。each()、create_function()、文字列中の ${}、暗黙の nullable 型、(integer) キャストなどは Rector でほぼ自動変換できます。
  4. 段階的に移しながら Deprecated を集める。 error_reporting=E_ALL、display_errors=Off、log_errors=On にして、Deprecated を全件ログに出して潰します。5.x 起点は 7.4 を経由する 2 段階移行にして、7.0 の山と 8.0 の山を分けて越えるほうがデバッグしやすくなります。
  5. 静かに壊れる項目を重点的にテストする。 エラーを出さずに結果だけ変わるものが本当の敵です。== による比較 [8.0]、ENT_QUOTES の既定化 [8.1]、PDO のネイティブ型 [8.1]、strtolower() のロケール非依存化 [8.2]、range() [8.3]、round() [8.4]、foreach と変数構文 [7.0]、htmlspecialchars() の UTF-8 既定 [5.4] は、各論ページの「特に危ない変更」で個別に取り上げています。

コーディングエージェントに任せるには

項目数が 100 を超える起点では、1 項目ずつ人が grep して直すより、Claude Code や Codex のようなコーディングエージェントに機械的な部分を任せたほうが早く終わります。ただし任せ方を間違えると、テストの無いところで静かに挙動が変わります。各論ページの「コーディングエージェントに一括で任せる」節に、その起点と移行先を埋め込んだ完成形のプロンプト、CLAUDE.md / AGENTS.md に書く移行ルールの例、使える静的解析ツールの設定例を載せました。ここでは考え方だけ書きます。

  • 先に道具で洗い出させる。 PHPCompatibility、Rector、PHPStan の結果を渡すと、エージェントが勘で探すより漏れが減ります。
  • 本特集の一覧を「チェックリスト」として渡す。 各論ページの項目には #v80-05 のような id が付いているので、「この URL の項目を 1 つずつ確認し、該当箇所と対応を表で報告して」と頼めます。
  • テストが無ければ、改修前に現状の出力を記録させる。 主要な画面や API の出力を保存しておき、移行先の PHP(Docker 公式イメージなど)で同じ出力になるかを比べます。
  • 人が判断するところは渡さない。 業務ロジックの意味が変わる修正、データベースの文字コード移行、本番の切り替えは、エージェントの提案を見たうえで人が決めます。

起点バージョン別ページ一覧

いま動いている系列のページを開いてください。どのページも、移行先を 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 から選ぶと、必要な項目数と一覧が切り替わります。

参照した一次情報

脆弱性

各版の移行ガイド(php.net)

各論ページの変更一覧は、次の移行ガイドと php-src の UPGRADING を元にしています。変更の一覧には、項目ごとに版別の公式リンクを付けました。

📌 ※2026年10月23日時点の公開情報に基づきます。脆弱性の影響範囲、悪用の状況、各ベンダーのバックポートの提供状況は日々更新されます。対応を決める前に、上の一次情報とお使いのディストリビューション・ホスティング事業者の告知を必ず確認してください。

🔖 各論ページで改修を進めながら、迷ったらこのページに戻ってきてください。ページ上部のブックマーク案内から URL をコピーできます。

免責事項(瑕疵担保・保証はありません)

本特集に掲載したコード・コマンド・設定例・エージェント向けプロンプトは、あくまで説明のための例です。お使いのソースコードや環境でそのまま動くこと、改修が漏れなく完了することを保証するものではありません。各変更点の最終確認は、php.net の公式 ChangeLog・移行ガイド、php-src の UPGRADING など一次情報で必ず行ってください。

本特集の内容は現状有姿で提供するものであり、正確性・完全性・有用性について、瑕疵担保責任・契約不適合責任を含め、当方(野口真一)はいかなる保証も行いません。本特集の内容やコードを利用したこと、または利用できなかったことにより生じた損害について、当方は一切の責任を負いません。

PHP の移行計画をご相談ください

「どの版へ、どの順で移すか」「エージェントにどこまで任せてよいか」から、
古い PHP アプリの棚卸しと改修計画づくりまで、30分の無料相談で承ります。

無料相談を予約する →