跳轉至內容

升級指南

高影響變更

中等影響變更

低影響變更

從 12.x 升級至 13.0

預計升級時間:10 分鐘

我們儘量記錄了所有可能的破壞性變更。由於其中一些變更位於框架的邊緣部分,因此只有一部分可能會影響您的應用程式。為了節省時間,您可以使用 Shift。Shift 是一個由社群維護的服務,可自動完成 Laravel 升級。

使用 AI 升級

您可以使用 Laravel Boost 自動升級。Boost 是一個官方的 MCP 伺服器,可為您的 AI 助手提供引導式升級提示——一旦安裝在任何 Laravel 12 應用程式中,只需在 Claude Code、Cursor、OpenCode、Gemini 或 VS Code 中使用 /upgrade-laravel-v13 斜槓命令,即可開始升級到 Laravel 13。

更新依賴

影響可能性:高

您應該更新應用程式 composer.json 檔案中的以下依賴項:

  • laravel/framework 更新為 ^13.0
  • laravel/tinker 更新為 ^3.0
  • phpunit/phpunit 更新為 ^12.0
  • pestphp/pest 更新為 ^4.0

更新 Laravel 安裝程式

如果您使用 Laravel 安裝程式 CLI 工具來建立新的 Laravel 應用程式,則應更新您的安裝程式以保持與 Laravel 13.x 的相容性。

如果您透過 composer global require 安裝了 Laravel 安裝程式,則可以使用 composer global update 更新它。

1composer global update laravel/installer

或者,如果您使用的是 Laravel Herd 捆綁的 Laravel 安裝程式,則應將 Herd 更新到最新版本。

快取

影響可能性:低

Laravel 的預設快取和 Redis 鍵字首現在使用連字元字尾。此外,預設的會話 Cookie 名稱現在使用 Str::snake(...) 來處理應用程式名稱。

在大多數應用程式中,此更改不會產生影響,因為應用程式級的配置檔案已經定義了這些值。這主要影響那些在缺少相應應用程式配置值時依賴框架級回退配置的應用程式。

如果您的應用程式依賴於這些自動生成的預設值,升級後快取鍵和會話 Cookie 名稱可能會發生變化。

1// Laravel <= 12.x
2Str::slug((string) env('APP_NAME', 'laravel'), '_').'_cache_';
3Str::slug((string) env('APP_NAME', 'laravel'), '_').'_database_';
4Str::slug((string) env('APP_NAME', 'laravel'), '_').'_session';
5 
6// Laravel >= 13.x
7Str::slug((string) env('APP_NAME', 'laravel')).'-cache-';
8Str::slug((string) env('APP_NAME', 'laravel')).'-database-';
9Str::snake((string) env('APP_NAME', 'laravel')).'_session';

要保留以前的行為,請在您的環境中顯式配置 CACHE_PREFIXREDIS_PREFIXSESSION_COOKIE

StoreRepository 契約:touch

影響可能性:非常低

快取契約現在包含一個用於擴充套件專案 TTL 的 touch 方法。如果您維護自定義的快取驅動實現,則需要新增此方法。

1// Illuminate\Contracts\Cache\Store
2public function touch($key, $seconds);

快取 serializable_classes 配置

影響可能性:中

預設的應用程式 cache 配置現在包含一個設定為 falseserializable_classes 選項。這強化了快取反序列化行為,如果您的 APP_KEY 被洩露,有助於防止 PHP 反序列化小工具鏈攻擊。如果您的應用程式有意在快取中儲存 PHP 物件,您應該顯式列出可以反序列化的類。

1'serializable_classes' => [
2 App\Data\CachedDashboardStats::class,
3 App\Support\CachedPricingSnapshot::class,
4],

如果您的應用程式之前依賴於反序列化任意快取物件,則需要將該用法遷移到顯式的類白名單,或遷移到非物件快取負載(例如陣列)。

容器

Container::call 與可空類預設值

影響可能性:低

Container::call 現在在沒有繫結存在時尊重可空類引數的預設值,這與 Laravel 12 中引入的建構函式注入行為相匹配。

1$container->call(function (?Carbon $date = null) {
2 return $date;
3});
4 
5// Laravel <= 12.x: Carbon instance
6// Laravel >= 13.x: null

如果您的方法呼叫注入邏輯依賴於之前的行為,您可能需要對其進行更新。

契約 (Contracts)

Dispatcher 契約:dispatchAfterResponse

影響可能性:非常低

Illuminate\Contracts\Bus\Dispatcher 契約現在包含 dispatchAfterResponse($command, $handler = null) 方法。

如果您維護了自定義的排程器實現,請將此方法新增到您的類中。

ResponseFactory 契約:eventStream

影響可能性:非常低

Illuminate\Contracts\Routing\ResponseFactory 契約現在包含 eventStream 簽名。

如果您維護了此契約的自定義實現,則應新增此方法。

MustVerifyEmail 契約:markEmailAsUnverified

影響可能性:非常低

Illuminate\Contracts\Auth\MustVerifyEmail 契約現在包含 markEmailAsUnverified()

如果您提供了此契約的自定義實現,請新增此方法以保持相容性。

資料庫

帶有 JOIN, ORDER BYLIMIT 的 MySQL DELETE 查詢

影響可能性:低

Laravel 現在為 MySQL 語法編譯完整的 DELETE ... JOIN 查詢,包括 ORDER BYLIMIT

在以前的版本中,ORDER BY / LIMIT 子句在連線刪除操作中可能會被靜默忽略。在 Laravel 13 中,這些子句被包含在生成的 SQL 中。因此,不支援此語法的資料庫引擎(如標準 MySQL / MariaDB 變體)現在可能會丟擲 QueryException,而不是執行無限制的刪除。

Eloquent

模型啟動與巢狀例項化

影響可能性:非常低

現在禁止在模型啟動期間建立新的模型例項,這會丟擲 LogicException

這會影響在模型 boot 方法或 trait boot* 方法內部例項化模型的程式碼。

1protected static function boot()
2{
3 parent::boot();
4 
5 // No longer allowed during booting...
6 (new static())->getTable();
7}

請將此邏輯移出啟動週期,以避免巢狀啟動。

多型中間表名稱生成

影響可能性:低

當為使用自定義中間表模型的物件使用多型表名推斷時,Laravel 現在會生成複數名稱。

如果您的應用程式依賴於之前用於多型中間表的單數推斷名稱,並且使用了自定義中間表類,則應在中間表模型上顯式定義表名。

集合模型序列化恢復預載入關聯

影響可能性:低

當 Eloquent 模型集合被序列化和恢復(例如在佇列任務中)時,現在會為集合中的模型恢復預載入的關聯。

如果您的程式碼依賴於反序列化後關聯不存在的狀態,您可能需要調整該邏輯。

HTTP 客戶端

HTTP 客戶端 Response::throwthrowIf 簽名

影響可能性:非常低

HTTP 客戶端響應方法現在在其方法簽名中聲明瞭回撥引數。

1public function throw($callback = null);
2public function throwIf($condition, $callback = null);

如果您在自定義響應類中重寫了這些方法,請確保您的方法簽名是相容的。

通知

預設密碼重置主題

影響可能性:非常低

Laravel 的預設密碼重置郵件主題已更改。

1// Laravel <= 12.x
2Reset Password Notification
3
4// Laravel >= 13.x
5Reset your password

如果您的測試、斷言或翻譯覆蓋依賴於之前的預設字串,請相應地更新它們。

佇列通知與缺失模型

影響可能性:非常低

佇列通知現在尊重通知類上定義的 #[DeleteWhenMissingModels] 屬性和 $deleteWhenMissingModels 屬性。

在以前的版本中,即使在您預期刪除它們的情況下,缺失的模型仍可能導致佇列通知任務失敗。

佇列

JobAttempted 事件異常負載

影響可能性:低

Illuminate\Queue\Events\JobAttempted 事件現在透過 $exception 屬性公開異常物件(或 null),取代了之前的布林值 $exceptionOccurred 屬性。

1// Laravel <= 12.x
2$event->exceptionOccurred;
3 
4// Laravel >= 13.x
5$event->exception;

如果您正在監聽此事件,請相應地更新監聽器程式碼。

QueueBusy 事件屬性重新命名

影響可能性:低

Illuminate\Queue\Events\QueueBusy 事件的 $connection 屬性已重新命名為 $connectionName,以與其他佇列事件保持一致。

如果您的監聽器引用了 $connection,請將其更新為 $connectionName

Queue 契約方法補充

影響可能性:非常低

Illuminate\Contracts\Queue\Queue 契約現在包含了以前僅在文件塊中宣告的佇列大小檢查方法。

如果您維護了此契約的自定義佇列驅動實現,請新增以下方法的實現:

  • pendingSize
  • delayedSize
  • reservedSize
  • creationTimeOfOldestPendingJob

路由

域名路由註冊優先順序

影響可能性:低

在路由匹配中,具有顯式域名的路由現在優先於非域名路由。

即使非域名路由註冊得更早,這也允許全匹配子域名路由保持一致的行為。如果您的應用程式依賴於之前域名和非域名路由之間的註冊優先順序,請審查路由匹配行為。

排程

withScheduling 註冊時機

影響可能性:非常低

透過 ApplicationBuilder::withScheduling() 註冊的計劃現在會推遲到 Schedule 解析時執行。

如果您的應用程式依賴於引導期間的即時計劃註冊時機,您可能需要調整該邏輯。

安全

請求偽造保護

影響可能性:高

Laravel 的 CSRF 中介軟體已從 VerifyCsrfToken 重新命名為 PreventRequestForgery,並且現在使用 Sec-Fetch-Site 請求頭包含請求源驗證。

VerifyCsrfTokenValidateCsrfToken 仍然作為棄用的別名保留,但應將直接引用更新為 PreventRequestForgery,特別是在測試或路由定義中排除中介軟體時。

1use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
2use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
3 
4// Laravel <= 12.x
5->withoutMiddleware([VerifyCsrfToken::class]);
6 
7// Laravel >= 13.x
8->withoutMiddleware([PreventRequestForgery::class]);

中介軟體配置 API 現在也提供了 preventRequestForgery(...) 方法。

支援

管理器 extend 回撥繫結

影響可能性:低

透過管理器 extend 方法註冊的自定義驅動閉包現在繫結到管理器例項上。

如果您之前在這些回撥內部將其他繫結物件(如服務提供者例項)作為 $this 使用,則應使用 use (...) 將這些值移至閉包捕獲中。

Str 工廠在測試間重置

影響可能性:低

Laravel 現在在測試結束時重置自定義的 Str 工廠。

如果您的測試依賴於自定義 UUID / ULID / 隨機字串工廠在測試方法間保持永續性,則應在每個相關測試或設定鉤子中重新設定它們。

Js::from 預設使用未轉義的 Unicode

影響可能性:非常低

Illuminate\Support\Js::from 現在預設使用 JSON_UNESCAPED_UNICODE

如果您的測試或前端輸出比較依賴於轉義的 Unicode 序列(例如 \u00e8),請更新您的預期結果。

檢視

分頁 Bootstrap 檢視名稱

影響可能性:低

Bootstrap 3 預設設定的內部分頁檢視名稱現在更加明確。

1// Laravel <= 12.x
2pagination::default
3pagination::simple-default
4
5// Laravel >= 13.x
6pagination::bootstrap-3
7pagination::simple-bootstrap-3

如果您的應用程式直接引用了舊的分頁檢視名稱,請更新這些引用。

其他

我們還鼓勵您檢視 laravel/laravel GitHub 倉庫中的更改。雖然許多更改並非強制要求,但您可能希望保持這些檔案與您的應用程式同步。其中一些更改將包含在本升級指南中,但其他更改(例如配置檔案或註釋的更改)則不會。您可以透過 GitHub 比較工具輕鬆檢視更改,並選擇對您重要的更新。