前言
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
extendcallback 的 binding - MySQL
DELETEquery (JOIN / ORDER BY / LIMIT) - 分頁 Bootstrap view 名稱
- 多型 pivot 資料表名稱的產生
QueueBusy事件屬性重新命名Strfactory 的測試間重置
升級步驟
更新依賴套件
影響程度:高 請更新composer.json 中以下依賴。
更新 Laravel installer
影響程度:高 若使用 Laravel installer CLI 建立新的 Laravel 應用程式,請更新為支援 Laravel 13.x 的版本。 若以composer global require 安裝時:
破壞性變更 (Breaking Changes)
安全性
防止請求偽造
影響程度:高 Laravel 的 CSRF middleware 已從VerifyCsrfToken 改名為 PreventRequestForgery。另外還新增了使用 Sec-Fetch-Site header 驗證請求來源的功能。
VerifyCsrfToken 與 ValidateCsrfToken 作為棄用的 alias 仍保留,但所有直接引用的位置都需更新為 PreventRequestForgery。尤其在測試或路由定義中若有排除 middleware,需要特別注意。
preventRequestForgery(...)。
快取
快取前綴與 session cookie 名稱
影響程度:低 Laravel 的預設快取與 Redis key 前綴改為使用連字號分隔的後綴。另外,預設 session cookie 名稱也改為使用Str::snake(...)。
大部分應用程式會在設定檔明確設定值,因此不會受此變更影響。只有依賴框架 fallback 設定的應用程式會受影響。
.env 檔明確設定。
快取 serializable_classes 設定
影響程度:中
預設 cache 設定新增了 serializable_classes 選項,預設為 false。這可在 APP_KEY 洩漏時防止 PHP 反序列化 gadget chain 攻擊。
若應用程式刻意在快取中儲存 PHP 物件,需要明確列出允許反序列化的類別。
Session serialization 設定
影響程度:中
Laravel 13 的 skeleton(laravel/laravel)的 config/session.php 中新增了 'serialization' => 'json'。不過,框架內部的預設仍是 php。
官方的升級指南沒有記載此設定的變更。這可推測是 不需要變更 的意圖。Laravel 中從前一版本升級時偶爾會有不影響升級的變更未在升級指南中記載。數年後升級時若找不到資訊會很困擾,因此非官方的紀錄很重要。
要維持與 Laravel 12 以前相同的行為,請明確設定 'serialization' => 'php'。
Container
Container::call 與 Nullable 類別預設值
影響程度:低
Container::call 在沒有 binding 時,會尊重 nullable 類別參數的預設值(與 Laravel 12 中對 constructor injection 引入的行為一致)。
資料庫
MySQL DELETE query
影響程度:低
Laravel 現在會以 MySQL 語法 compile 完整的 DELETE ... JOIN query(含 ORDER BY 與 LIMIT)。
之前版本中,帶 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 名稱已明確化。已棄用的功能
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 宣告)。
pendingSizedelayedSizereservedSizecreationTimeOfOldestPendingJob
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 的 pendingSize、delayedSize、reservedSize 等方法,可以更細緻地監控佇列狀態。
常見遷移問題與解法
問題:與 CSRF 相關的測試失敗
症狀: 引用VerifyCsrfToken 的測試因找不到類別而失敗。
解法: 將所有引用更新為 PreventRequestForgery。
問題:無法從快取恢復物件
症狀: 從快取取得的資料變成null,或發生 UnserializationFailedException。
解法: 在 config/cache.php 的 serializable_classes 中新增要使用的類別,或將快取的值轉為陣列。
問題:JobAttempted listener 無法運作
症狀: $event->exceptionOccurred 為 null 或發生未定義錯誤。
解法: 改為 $event->exception !== null。
問題:Session 無效化
症狀: 升級後使用者被登出。 解法: 預設 session cookie 名稱已變更。請在.env 明確設定 SESSION_COOKIE 以維持之前的值。
問題:找不到快取 key
症狀: 升級後 cache miss 增加。 解法: 快取前綴已變更。請在.env 設定 CACHE_PREFIX,或清除快取。
參考資料
- 官方升級指南(英文)
- laravel/laravel repository 差異(12.x → 13.x)
- Laravel Shift — 自動化升級的社群服務
- Laravel Boost — 用於 AI 輔助升級的 MCP server