前言
Laravel 13 于 2026 年 3 月发布。本指南讲解从 Laravel 12.x 升级到 13.x 的操作步骤。预计升级时间约 10 分钟。当然,破坏性变更对应用的影响会因规模和所用功能而异。
使用 AI 升级
也可以用 Laravel Boost 自动化升级。Boost 是官方的 MCP 服务器,能为 AI 助手提供分步的升级提示。装到 Laravel 12 应用后,可以在 Claude Code、Cursor、OpenCode、Gemini、VS Code 中通过/upgrade-laravel-v13 斜杠命令开始升级到 Laravel 13。该命令需要 laravel/boost ^2.0。
即便你使用的 AI 工具不支持斜杠命令,也可以直接引用提示词文件,执行相同的升级步骤。把下面的 prompt 原样贴给 AI 即可。
提示词
按影响面分级的变更
影响度:高
- 依赖更新
- Laravel installer 更新
- 请求伪造防御(CSRF)
影响度:中
- 缓存
serializable_classes设置 - Session
serialization设置
影响度:低
- 缓存前缀与 session Cookie 名
- 集合模型的序列化
Container::call与 Nullable 类的默认值- 域名路由注册的优先级
JobAttempted事件的异常载荷- Manager
extend回调的绑定 - MySQL
DELETE查询(JOIN / ORDER BY / LIMIT) - 分页 Bootstrap 视图名
- 多态 pivot 表名的生成
QueueBusy事件的属性名变更Strfactory 在测试间的重置
升级步骤
更新依赖
影响度:高 请更新composer.json 中的以下依赖。
更新 Laravel installer
影响度:高 如果你用 Laravel installer CLI 创建新项目,请把它升到兼容 Laravel 13.x 的版本。 用composer global require 安装的情况:
破坏性变更(Breaking Changes)
安全
请求伪造防御
影响度:高 Laravel 的 CSRF 中间件从VerifyCsrfToken 重命名为 PreventRequestForgery。同时新增了基于 Sec-Fetch-Site 头的请求来源校验。
VerifyCsrfToken 和 ValidateCsrfToken 会作为废弃别名保留,但所有直接引用它们的地方都需要改成 PreventRequestForgery。特别是在测试或路由定义中排除该中间件时要留意。
preventRequestForgery(...)。
缓存
缓存前缀与 session Cookie 名
影响度:低 Laravel 默认的缓存及 Redis 键前缀现在使用连字符风格的后缀。默认的 session Cookie 名也改为使用Str::snake(...)。
由于大多数应用都会在配置里显式设定值,所以只有依赖框架回退默认值的应用会受影响。
.env 里显式设置。
缓存 serializable_classes 设置
影响度:中
默认的 cache 配置新增了 serializable_classes 选项,默认为 false。这样即使 APP_KEY 泄露,也能防御 PHP 反序列化 gadget 链攻击。
如果你的应用确实在缓存里存 PHP 对象,需要显式把允许反序列化的类列出来。
Session serialization 设置
影响度:中
Laravel 13 的骨架(laravel/laravel)在 config/session.php 里加入了 'serialization' => 'json'。但框架内部的默认值仍然是 php。
官方升级指南没有提到这个改动。这大概意味着 不必更改。Laravel 有时在“上一个大版本”升级到当前版本的指南中不会记录这类变化。数年后再升级时,如果没有信息会很麻烦,所以民间记录也很重要。
要保持与 Laravel 12 及以前一致的行为,请显式设置 'serialization' => 'php'。
容器
Container::call 与 Nullable 类的默认值
影响度:低
Container::call 在没有绑定时会尊重 nullable 类参数的默认值(和 Laravel 12 中构造注入的行为一致)。
数据库
MySQL DELETE 查询
影响度:低
Laravel 现在会为 MySQL 语法编译完整的、带 ORDER BY 和 LIMIT 的 DELETE ... JOIN 查询。
以前带 JOIN 的 DELETE 里 ORDER BY / LIMIT 子句会被忽略。Laravel 13 会把这些子句写进生成的 SQL 中。这在不支持该语法的数据库引擎上可能引发 QueryException。
Eloquent
多态 pivot 表名的生成
影响度:低 使用自定义 pivot 模型类的多态 pivot 模型在推断表名时,Laravel 会生成复数形式。 如果依赖此前推断出的单数形式表名,请在 pivot 模型里显式定义表名。集合模型的序列化
影响度:低 Eloquent 模型集合被序列化和恢复(比如推入队列的作业)时,会为模型恢复被 eager 加载的关联。 如果你有代码依赖“反序列化后关联不存在”这一点,需要修改。队列
JobAttempted 事件的异常载荷
影响度:低
Illuminate\Queue\Events\JobAttempted 事件用 $exception(异常对象或 null)取代了原先的 boolean 属性 $exceptionOccurred。
QueueBusy 事件的属性名变更
影响度:低
为了和其他队列事件保持一致,Illuminate\Queue\Events\QueueBusy 事件的属性 $connection 重命名为 $connectionName。
路由
域名路由注册的优先级
影响度:低 有明确域名的路由在匹配时会优先于无域名路由。 这样即便无域名路由先注册,catchall 的子域名路由也能一致工作。支持
Manager extend 回调的绑定
影响度:低
通过 Manager 的 extend 方法注册的自定义驱动闭包会被绑定到 manager 实例上。
如果之前这些回调里的 $this 引用了别的对象(例如服务提供者实例),需要用 use (...) 把它捕获到闭包里。
Str factory 在测试间的重置
影响度:低
Laravel 现在会在测试 teardown 时重置自定义的 Str factory。
如果你依赖自定义 UUID / ULID / 随机字符串 factory 在多个测试之间保持,请在每个相关测试或 setup 钩子中重新配置。
视图
分页 Bootstrap 视图名
影响度:低 Bootstrap 3 默认的内置分页视图名变得更明确。已废弃的功能
| 功能 | 替代 |
|---|---|
VerifyCsrfToken 中间件 | PreventRequestForgery |
ValidateCsrfToken 中间件 | PreventRequestForgery |
JobAttempted::$exceptionOccurred | JobAttempted::$exception |
QueueBusy::$connection | QueueBusy::$connectionName |
契约新增
影响度:非常低 只对有自定义实现的场景有影响。Dispatcher 契约
Illuminate\Contracts\Bus\Dispatcher 契约新增了 dispatchAfterResponse($command, $handler = null) 方法。
ResponseFactory 契约
Illuminate\Contracts\Routing\ResponseFactory 契约新增了 eventStream 签名。
MustVerifyEmail 契约
Illuminate\Contracts\Auth\MustVerifyEmail 契约新增了 markEmailAsUnverified()。
Queue 契约
Illuminate\Contracts\Queue\Queue 契约新增了以下队列体积检查方法(以前只在 docblock 中声明):
pendingSizedelayedSizereservedSizecreationTimeOfOldestPendingJob
Store / Repository 契约
缓存契约新增了用于延长 TTL 的 touch 方法。
新功能亮点
AI 辅助升级(Laravel Boost)
Laravel Boost 是官方 MCP 服务器。它与 AI 编辑器联动,通过/upgrade-laravel-v13 命令半自动完成升级。
通过 Sec-Fetch-Site 头做来源校验
PreventRequestForgery 中间件增加了基于 Sec-Fetch-Site 头的来源校验,加固了 CSRF 保护。
安全的缓存反序列化
通过serializable_classes 设置,只有列入许可的类才会被反序列化。对 PHP 反序列化攻击的安全性得到提升。
SSE(Server-Sent Events)的 eventStream
ResponseFactory 契约新增了 eventStream,改进了 Server-Sent Events 支持。
队列可观测性提升
Queue 契约的 pendingSize、delayedSize、reservedSize 等方法让你可以更细粒度地监控队列状态。
常见迁移问题与解决方案
问题:CSRF 相关测试失败
**症状:**引用VerifyCsrfToken 的测试因“找不到类”而失败。
**解决:**把所有引用都改为 PreventRequestForgery。
问题:缓存中的对象无法恢复
**症状:**从缓存取到的数据变成null,或抛 UnserializationFailedException。
**解决:**在 config/cache.php 的 serializable_classes 中加入要使用的类,或把缓存的值转成数组。
问题:JobAttempted 监听器不工作
症状:$event->exceptionOccurred 变成 null 或报未定义错误。
**解决:**改成 $event->exception !== null。
问题:session 失效
**症状:**升级后用户被强制登出。 **解决:**默认的 session Cookie 名变了。在.env 里显式设置 SESSION_COOKIE 以保留原值。
问题:找不到缓存键
**症状:**升级后缓存 miss 增多。 **解决:**缓存前缀变了。在.env 里设置 CACHE_PREFIX,或清理缓存。
参考资料
- 官方升级指南(英文)
- laravel/laravel 仓库差异(12.x → 13.x)
- Laravel Shift —— 自动化升级的社区服务
- Laravel Boost —— AI 辅助升级的 MCP 服务器