【PHP】Laravel 12から13へアップグレードする方法(PHP 8.3必須)

Laravel 12.x のアプリケーションを 13.x へ上げるときは、公式のアップグレードガイド「Upgrading To 13.0 From 12.x」に沿って進めます。所要時間の目安は 10 分と案内されています。Laravel 13.x では PHP 8.3 以上が必須です。

この記事の対象は Laravel 13.x(12.x からのアップグレード)と PHP 8.3 以上です。検証の記録では、laravel/laravel v12.12.2(laravel/framework v12.72.0)の新規アプリケーションを、公式ガイドどおりの composer.json 更新と composer update --with-all-dependencies で laravel/framework v13.42.0 まで上げ、PHP 8.4.27 / Composer 2.10.3 で php artisan test がアップグレード前後とも 2 passed、composer audit は指摘なしでした。PHP 8.3 だけの実行ログは、この検証には含まれていません。

新規に 13.x を入れる手順ではなく、既存の 12.x アプリケーションを上げる話です。新規インストールの入門は、Laravel入門:インストールから簡単なサンプルアプリケーションの作成 を参照してください。

前提

  • いま動いているアプリケーションが Laravel 12.x であること
  • 実行環境の PHP が 8.3 以上であること
  • 公式ガイド(Upgrade Guide – Laravel 13.x)を手元で開いておくこと

公式ガイドには、Laravel インストーラの更新(影響度 High)もあります。この記事の検証は composer create-project "laravel/laravel:^12.0" で作ったアプリケーションのアップグレードであり、インストーラや Laravel Herd の手順は確認していません。

サポート期限

日付は、公式表の行をそのまま示します。取得元は php.net の Currently Supported Versions と、Laravel 13.x リリースノートの Support Policy 表です。

PHP(https://www.php.net/supported-versions.php)

Branch Initial Release Active Support Until Security Support Until
8.2 8 Dec 2022 31 Dec 2024 31 Dec 2026
8.3 23 Nov 2023 31 Dec 2025 31 Dec 2027
8.4 21 Nov 2024 31 Dec 2026 31 Dec 2028
8.5 20 Nov 2025 31 Dec 2027 31 Dec 2029

8.2 は、php.net/eol.php の表には載っていません(まだ EOL ではありません)。8.2 のアクティブサポートは終了済みで、セキュリティサポートは 31 Dec 2026 までです。8.3 のアクティブサポートも終了済みで、セキュリティサポートは 31 Dec 2027 までです。

Laravel(https://laravel.com/docs/13.x/releases Support Policy 表)

Version PHP (*) Release Bug Fixes Until Security Fixes Until
12 8.2 – 8.5 February 24th, 2025 August 13th, 2026 February 24th, 2027
13 8.3 – 8.5 March 17th, 2026 Q3 2027 March 17th, 2028

Laravel 13 の日付は、12.x のリリースノートではなく 13.x の表を正とします。2026-11-16 時点で、Laravel 12 のバグ修正期間は終了済みです(August 13th, 2026 以降)。セキュリティ修正は February 24th, 2027 まで続きます。

依存関係を更新する

公式ガイドの「Updating Dependencies」(影響度 High)では、次のように上げます。

  • laravel/framework を ^13.0
  • laravel/tinker を ^3.0
  • phpunit/phpunit を ^12.0
  • 使っている場合のみ、laravel/boost を ^2.0、pestphp/pest を ^4.0

PHP の要件は、13.x の「minimum PHP version of 8.3」に合わせ、^8.3 です。

検証で使った新規 12.12.2 スケルトンには laravel/boost と pestphp/pest は入っていなかったため、追加していません。composer.json の該当箇所を公式ガイドの下限に合わせたうえで、次を実行します。

composer update --with-all-dependencies

この検証ではコマンドは終了コード 0 で完了し、laravel/framework v13.42.0、laravel/tinker v3.1.0、phpunit/phpunit 12.5.44 に解決され、php artisan --version は Laravel Framework 13.42.0 を表示しました。更新中、古い PHPUnit 系パッケージの削除で pre_uninstall イベントの非致命エラーが出ましたが、処理は継続して終了コード 0 でした。

なお、現行の 13.x スケルトンの composer.json は laravel/framework ^13.17、phpunit/phpunit ^12.5.12 です。公式ガイドに書かれた ^13.0 / ^12.0 は下限で、この検証ではその下限から上記の 13.x / PHPUnit 12.x に解決されています。

上げたあとは、次で確認します。テストの書き方そのものは、Laravelでテストを実装する方法 も参照してください。

php artisan --version
php artisan test
composer audit

この検証では、アップグレード後の php artisan test も 2 passed(終了コード 0)、composer audit は “No security vulnerability advisories found.”(終了コード 0)でした。サードパーティパッケージ全般の互換表は、この検証の範囲外です。使っているパッケージは、それぞれのドキュメントで確認してください。

composer update だけでは入らない設定

依存関係の更新が終わっても、13.x スケルトンの設定ファイルまで自動では揃いません。とくに次の2点は、Composer の更新だけでは入りません。

cache.serializable_classes

公式ガイドの「Cache serializable_classes」(影響度 Medium)によると、13.x のアプリケーションスケルトンでは config/cache.php に serializable_classes が false で追加され、アンシリアライズを制限します。キャッシュに PHP オブジェクトを保存している場合は、許可するクラスを指定する必要があります。

Composer の更新だけでは、このキーは設定されません。検証では、laravel/laravel v12.12.2 を公式ガイドどおりの依存関係更新と composer update --with-all-dependencies で laravel/framework v13.42.0 にしたあとでも、config/cache.php に serializable_classes は追加されず、実行時の config("cache.serializable_classes") は UNSET のままでした。キーが未設定のときは、従来どおり制限のない unserialize() が使われます。硬化を効かせるには、13.x の設定を同期するか、このキーを自分で設定する必要があります。オブジェクトの許可リストが実行時にどう働くかまでは、この検証では確認していません。

キャッシュ全般の使い方は、Laravelでキャッシュを実装する方法 も参照してください。

セッションの serialization

13.x スケルトンの config/session.php は serialization を json にします。一方、Composer だけで上げた 12.x アプリケーションには、このキーは入りません。検証ではキーが無く、実行時の config("session.serialization") は UNSET、フレームワークのデフォルトは php のままでした。アクティブなセッションは、設定を同期するまで無効化されません。公式ガイドでは、セッションを維持するなら php のままにし、セッションにオブジェクトを入れない場合は json への変更を推奨しています。json に切り替えると、アクティブなセッションは無効になります。

押さえておきたい破壊的変更

公式ガイドには、このほかにも項目があります。ここでは、検証で確認できた範囲だけを書きます。未実施の項目の動きは断定せず、ガイド本体を見てください。

CSRF ミドルウェアの名前

「Request Forgery Protection」(影響度 High)では、CSRF ミドルウェアが VerifyCsrfToken から PreventRequestForgery に改名されています。VerifyCsrfToken と ValidateCsrfToken は非推奨のエイリアスとして残っています。withoutMiddleware やルート定義では PreventRequestForgery を使うことが推奨されています。laravel/framework v13.42.0 では、3クラスとも存在し、VerifyCsrfToken は PreventRequestForgery のサブクラスであることを確認しています。Sec-Fetch-Site を使った HTTP 上の挙動は、この検証では確認していません。

ミドルウェアの実装については、Laravelでミドルウェアを実装する方法 も参照してください。

upsert の uniqueBy

「Database upsert」(影響度 Medium)では、uniqueBy が空でないことが検証され、空のときは InvalidArgumentException になります。検証では SQLite 上で uniqueBy: [] が “The unique columns must not be empty.” を投げました。ガイドにある MySQL / MariaDB 固有のインデックス検出の話は、この検証では実行していません。

Cache::touch

Store と Repository の契約に touch が追加されています(影響度 Very Low)。検証では、デフォルトの database ストアで Cache::touch が true を返し、値は残っていました。

キューイベントのプロパティ

JobAttempted は $exception を公開し、以前の $exceptionOccurred を置き換えます。QueueBusy は $connectionName を公開します。laravel/framework v13.42.0 の reflection で、それぞれのプロパティの有無を確認しています。リスナーを端から端まで実行してはいません。

array_first / array_last

PHP 8.5 未満では、Laravel 13 が同梱する symfony/polyfill-php85 がグローバルの array_first() / array_last() を定義し、先頭・末尾の要素を返します(かつてのコールバックで絞り込むヘルパーではありません)。検証は PHP 8.4.27 で、array_first(['a','b']) === 'a' でした。このアプリケーションに laravel/helpers は含まれておらず、衝突は見られませんでした。コールバックで絞り込む場合は、ガイドのとおり Illuminate\Support\Arr::first を使ってください。

パスワードリセットメールの件名

Laravel 13 のデフォルトのパスワードリセットメール件名は “Reset your password” です(以前は “Reset Password Notification”)。laravel/framework v13.42.0 のソースにこの文字列があることを確認しています。実際のメール送信はしていません。

公式ガイドで確認する残りの項目

次のような項目は、この検証では実行していないか、契約やメソッドの存在確認までに留めています。本文で動きを断定しません。詳細は Upgrade Guide – Laravel 13.x を見てください。

  • Container::call の nullable デフォルト
  • ドメインルートの優先、モデルの boot 中の new static、ポリモーフィック pivot のテーブル名
  • Collection の eager 関係の復元、キュー通知の欠落モデル、withScheduling の登録タイミング
  • HTTP throw / throwIf の実行時、Pagination の Bootstrap ビュー名、Js::from の Unicode など

スケルトン全体の同期(Sail の扱い、laravel/pao の追加など)は、公式の 12.x…13.x 比較にまとまっています。ガイドは、スケルトンの変更の多くを必須ではないとしています。この検証では、文書化された composer.json の依存関係更新を適用し、13.x スケルトンのファイル一式はコピーしていません。

まとめ

  • Laravel 13.x へのアップグレードでは PHP 8.3 以上が必要です
  • laravel/framework ^13.0、laravel/tinker ^3.0、phpunit/phpunit ^12.0 など、公式ガイドの依存関係を更新して composer update --with-all-dependencies を実行します
  • cache.serializable_classes は Composer の更新だけでは設定されません。13.x の設定を同期するか、キーを自分で入れる必要があります
  • セッションの serialization も同様に、Composer の更新だけでは入りません
  • CSRF ミドルウェアは PreventRequestForgery を優先し、空の uniqueBy は例外になります
  • 日付と残り項目の詳細は、php.net と Laravel 13.x の公式ドキュメントを確認してください

既存アプリケーションのバージョンアップを進めたい場合は、当社(ノマドシステム工房)の保守・バージョンアップ診断もあります。

出典

コメントする