Skip to main content

前言

Laravel 13 於 2026 年 3 月發佈。本指南說明從 Laravel 12.x 升級到 13.x 的步驟。
升級預估所需時間約為 10 分鐘。不過破壞性變更對應用程式的影響會因規模與使用的功能而異。

使用 AI 進行升級

也可以使用 Laravel Boost 自動化升級。Boost 是官方的 MCP server,會向 AI 助理提供逐步的升級提示。安裝到 Laravel 12 應用後,可在 Claude Code、Cursor、OpenCode、Gemini、VS Code 中使用 /upgrade-laravel-v13 斜線指令開始升級到 Laravel 13。此指令需要 laravel/boost ^2.0 即使是不支援斜線指令的 AI 工具,也可直接參照 prompt 檔案來執行同樣的升級步驟。請將以下 prompt 直接貼給 AI。
prompt

依影響程度分類的變更

影響程度:高

  • 更新依賴套件
  • 更新 Laravel installer
  • 防止請求偽造(CSRF)

影響程度:中

  • 快取 serializable_classes 設定
  • Session serialization 設定

影響程度:低

  • 快取前綴與 session cookie 名稱
  • Collection model 的序列化
  • Container::call 與 Nullable 類別預設值
  • Domain 路由註冊的優先順序
  • JobAttempted 事件的例外 payload
  • Manager extend callback 的 binding
  • MySQL DELETE query (JOIN / ORDER BY / LIMIT)
  • 分頁 Bootstrap view 名稱
  • 多型 pivot 資料表名稱的產生
  • QueueBusy 事件屬性重新命名
  • Str factory 的測試間重置

升級步驟

更新依賴套件

影響程度:高 請更新 composer.json 中以下依賴。
若有使用 Laravel Boost 也一併更新。
更新後執行以下指令安裝依賴。

更新 Laravel installer

影響程度:高 若使用 Laravel installer CLI 建立新的 Laravel 應用程式,請更新為支援 Laravel 13.x 的版本。 若以 composer global require 安裝時:
若使用 Laravel Herd 的 bundle 版,請更新 Herd 自身至最新版本。

破壞性變更 (Breaking Changes)

安全性

防止請求偽造

影響程度:高 Laravel 的 CSRF middleware 已從 VerifyCsrfToken 改名為 PreventRequestForgery。另外還新增了使用 Sec-Fetch-Site header 驗證請求來源的功能。 VerifyCsrfTokenValidateCsrfToken 作為棄用的 alias 仍保留,但所有直接引用的位置都需更新為 PreventRequestForgery。尤其在測試或路由定義中若有排除 middleware,需要特別注意。
middleware 設定 API 也可使用 preventRequestForgery(...)

快取

影響程度:低 Laravel 的預設快取與 Redis key 前綴改為使用連字號分隔的後綴。另外,預設 session cookie 名稱也改為使用 Str::snake(...) 大部分應用程式會在設定檔明確設定值,因此不會受此變更影響。只有依賴框架 fallback 設定的應用程式會受影響。
若要維持之前的行為,請在 .env 檔明確設定。

快取 serializable_classes 設定

影響程度:中 預設 cache 設定新增了 serializable_classes 選項,預設為 false。這可在 APP_KEY 洩漏時防止 PHP 反序列化 gadget chain 攻擊。 若應用程式刻意在快取中儲存 PHP 物件,需要明確列出允許反序列化的類別。
若原本是反序列化任意快取物件,需要改為明確的類別允許清單,或改為非物件的快取 payload(如陣列)。

Session serialization 設定

影響程度:低 Laravel 13 的應用骨架(laravel/laravel)現在會將 config/session.phpserialization 設為 json。不過框架內部的預設值仍為 php
將此設定從 php 變更為 json 會使所有作用中的使用者 session 失效。若應用在 session 中儲存 PHP 物件,也可能造成錯誤。
若希望在升級時保留作用中的 session,請明確設為 php。若應用不會在 session 中儲存 PHP 物件,且可接受要求使用者重新登入,則可變更為 json 以獲得更好的安全性。
啟用 JSON 序列化前,請先確認應用不會在 session 中儲存 PHP 物件。

Container

Container::call 與 Nullable 類別預設值

影響程度:低 Container::call 在沒有 binding 時,會尊重 nullable 類別參數的預設值(與 Laravel 12 中對 constructor injection 引入的行為一致)。

資料庫

MySQL DELETE query

影響程度:低 Laravel 現在會以 MySQL 語法 compile 完整的 DELETE ... JOIN query(含 ORDER BYLIMIT)。 之前版本中,帶 JOIN 的 DELETE 有時會忽略 ORDER BY / LIMIT 子句。Laravel 13 中這些子句會包含在產生的 SQL 中。結果是在不支援此語法的部分資料庫引擎中可能會發生 QueryException

Eloquent

多型 pivot 資料表名稱的產生

影響程度:低 推測使用自訂 pivot model 類別的多型 pivot model 的資料表名稱時,Laravel 現在會產生複數形的名稱。 若原本依賴之前的單數形推測名稱,請在 pivot model 中明確定義資料表名稱。

Collection model 的序列化

影響程度:低 Eloquent model collection 序列化與復原(如佇列 job)時,會為 model 復原 eager loaded 的 relation。 若程式碼依賴反序列化後 relation 不存在,需要修正。

佇列

JobAttempted 事件的例外 payload

影響程度:低 Illuminate\Queue\Events\JobAttempted 事件會將例外物件(或 null)暴露為 $exception,取代之前的 boolean $exceptionOccurred 屬性。

QueueBusy 事件屬性重新命名

影響程度:低 Illuminate\Queue\Events\QueueBusy 事件的屬性 $connection 為了與其他佇列事件保持一致,已改名為 $connectionName

路由

Domain 路由註冊的優先順序

影響程度:低 在路由匹配時,具明確 domain 的路由現在會優先於非 domain 路由。 如此一來,即使非 domain 路由先註冊,catch-all 子網域路由也能一致地運作。

支援

Manager extend callback 的 binding

影響程度:低 以 Manager 的 extend 方法註冊的自訂 driver closure,現在會 bind 到 manager instance。 若之前在這些 callback 中將其他物件(如 service provider instance)作為 $this 參照,需要用 use (...) 將值移至 closure capture。

Str factory 的測試間重置

影響程度:低 Laravel 會在測試 teardown 時重置自訂 Str factory。 若依賴自訂 UUID / ULID / 隨機字串 factory 在測試方法間持續存在,請改為在各相關測試或 setup hook 中設定。

View

分頁 Bootstrap view 名稱

影響程度:低 Bootstrap 3 預設的內部分頁 view 名稱已明確化。
若直接引用舊分頁 view 名稱,請進行更新。

已棄用的功能


Contract 新增

影響程度:非常低 僅有自訂實作時受影響。

Dispatcher contract

Illuminate\Contracts\Bus\Dispatcher contract 新增了 dispatchAfterResponse($command, $handler = null) 方法。

ResponseFactory contract

Illuminate\Contracts\Routing\ResponseFactory contract 新增了 eventStream 簽章。

MustVerifyEmail contract

Illuminate\Contracts\Auth\MustVerifyEmail contract 新增了 markEmailAsUnverified()

Queue contract

Illuminate\Contracts\Queue\Queue contract 新增了以下佇列大小檢查方法(先前僅以 docblock 宣告)。
  • pendingSize
  • delayedSize
  • reservedSize
  • creationTimeOfOldestPendingJob

Store / Repository contract

Cache contract 新增了用於延長 TTL 的 touch 方法。

新功能亮點

AI 輔助升級(Laravel Boost)

Laravel Boost 是官方 MCP server。可與 AI editor 連動,透過 /upgrade-laravel-v13 指令半自動化升級。

透過 Sec-Fetch-Site header 驗證請求來源

PreventRequestForgery middleware 會使用 Sec-Fetch-Site header 進行額外的來源驗證。這強化了 CSRF 保護。

安全的快取反序列化

透過 serializable_classes 設定,只有允許的類別會被反序列化。強化了對 PHP 反序列化攻擊的安全性。

SSE(Server-Sent Events)的 eventStream

ResponseFactory contract 新增了 eventStream,改善了對 Server-Sent Events 的支援。

佇列可見性提升

透過 Queue contract 的 pendingSizedelayedSizereservedSize 等方法,可以更細緻地監控佇列狀態。

常見遷移問題與解法

問題:與 CSRF 相關的測試失敗

症狀: 引用 VerifyCsrfToken 的測試因找不到類別而失敗。 解法: 將所有引用更新為 PreventRequestForgery

問題:無法從快取恢復物件

症狀: 從快取取得的資料變成 null,或發生 UnserializationFailedException 解法:config/cache.phpserializable_classes 中新增要使用的類別,或將快取的值轉為陣列。

問題:JobAttempted listener 無法運作

症狀: $event->exceptionOccurrednull 或發生未定義錯誤。 解法: 改為 $event->exception !== null

問題:Session 無效化

症狀: 升級後使用者被登出。 解法: 預設 session cookie 名稱已變更。請在 .env 明確設定 SESSION_COOKIE 以維持之前的值。

問題:找不到快取 key

症狀: 升級後 cache miss 增加。 解法: 快取前綴已變更。請在 .env 設定 CACHE_PREFIX,或清除快取。

參考資料

最後修改於 2026年8月21日