前言
本指南讲解如何将 Laravel 10 之前的旧应用结构(拥有Kernel 类以及多个 Service Provider 的结构)迁移到 Laravel 11 之后的 Slim Application Skeleton。
何时需要迁移
以下情况下可以考虑迁移:- 希望让项目符合最新的标准结构,方便新成员对照官方文档
- 希望与 Laravel 11 之后新建的包或 Starter Kit 保持结构一致
- 希望减少沿袭自旧结构的配置文件和类,让代码库更简洁
前置条件
本指南假设:- Laravel 版本升级已完成(
laravel/framework ^11.0及以上) - 现有测试全部通过
- 已理解 Laravel 11 之后的应用结构(参考Laravel 11 之后的应用结构)
迁移示例
下面演示如何在保留 Breeze(Blade 栈)的前提下,仅将 Laravel 10 + Breeze 项目的应用结构迁移到新结构。替换 bootstrap/app.php
旧的 新(Laravel 11 以后):
bootstrap/app.php 会创建 $app 实例并注册 Kernel。我们将它替换为 Application::configure() 的链式调用。旧(Laravel 10):withMiddleware() 与 withExceptions() 的回调是接收下一步将要删除的 Kernel 文件设置的地方。先保持为空,在后续步骤中再补充。删除 HTTP Kernel(app/Http/Kernel.php)
app/Http/Kernel.php 中定义了全局中间件、中间件组以及中间件别名。旧(app/Http/Kernel.php):app/Http/Kernel.php。如果有自定义(添加或移除了自定义中间件),请先将其迁移到 bootstrap/app.php 的 withMiddleware() 后再删除。app/Http/Kernel.php。在 Laravel 11 中,
TrustProxies、EncryptCookies、VerifyCsrfToken 等默认中间件类也可以从 app/Http/Middleware/ 中删除。这些类已内置在框架侧,如果不需要自定义,文件本身也可以不保留。删除 Console Kernel(app/Console/Kernel.php)
app/Console/Kernel.php 负责定义计划任务并自动加载命令。旧(app/Console/Kernel.php):app/Console/Commands/ 目录,因此不再需要写 $this->load()。计划任务的定义可以迁移到 routes/console.php 或 bootstrap/app.php 的 withSchedule()。app/Console/Kernel.php。请不要删除
app/Console/ 目录内的自定义 Artisan 命令文件。命令文件保持不动,仅删除 Kernel 类文件即可。删除异常处理器(app/Exceptions/Handler.php)
app/Exceptions/Handler.php 负责异常上报与渲染的配置。旧(app/Exceptions/Handler.php):bootstrap/app.php 的 withExceptions() 再删除。$dontFlash 添加过自定义字段的话,也可以按相同方式迁移。app/Exceptions/Handler.php。删除 RouteServiceProvider 并迁移路由注册
app/Providers/RouteServiceProvider.php 负责路由文件的加载与限流的配置。旧(app/Providers/RouteServiceProvider.php):bootstrap/app.php 的 withRouting()。AppServiceProvider::boot()。HOME 常量,请直接替换成 URL 字符串,或将常量迁移到 AppServiceProvider。迁移完成后,删除 app/Providers/RouteServiceProvider.php。整理 Service Provider
Laravel 10 默认提供了 5 个 Service Provider。请将它们整合到
迁移旧 app/Providers/AuthServiceProvider.php 内容的示例:删除不再需要的 Provider 文件后,删除 接着创建
AppServiceProvider.php 一个文件中。要删除的 Provider(将内容迁移到 AppServiceProvider 后删除):| 文件 | 迁移目的地 |
|---|---|
app/Providers/AuthServiceProvider.php | AppServiceProvider::boot() 中的 Gate::policy() 等 |
app/Providers/BroadcastServiceProvider.php | 若使用广播,则 bootstrap/app.php 的 withBroadcasting() |
app/Providers/EventServiceProvider.php | AppServiceProvider::boot() 中的 Event::listen() 等 |
app/Providers/RouteServiceProvider.php | 已在上一步处理 |
config/app.php 中的 providers 数组。bootstrap/providers.php 以适配新结构。当
bootstrap/providers.php 存在时,Laravel 会将其作为 Provider 列表优先加载。更新 Controller 基类
Laravel 10 的 新(Laravel 11 以后):trait 提供的功能按以下方式替代:
如果现有 Controller 使用了 trait 的方法,可以选择修改每个 Controller,或者在
Controller 基类使用了 AuthorizesRequests 和 ValidatesRequests trait。Laravel 11 的新基类是不包含这些 trait 的简单抽象类。旧(Laravel 10):| 旧方式(通过 trait) | 新方式 |
|---|---|
$this->validate($request, $rules) | $request->validate($rules) |
$this->authorize('update', $post) | Gate::authorize('update', $post) |
$this->authorizeResource(Post::class) | Laravel 11 中没有简单的替代方式,可保留 App\Http\Controllers\Controller 为 Laravel 10 的形式 |
Controller 基类中保留这些 trait。不必一次性全部改完也能运行。更新 .env、.env.example、phpunit.xml
CACHE_DRIVER 变为 CACHE_STORE 等,条目也有增删,如有需要请调整。
这类改动涉及 config 文件和生产环境,请谨慎处理。
不必强行跟进。迁移后的文件结构
迁移后的项目结构大致如下(展示相对旧结构的变化)。小结
| 迁移内容 | 旧位置 | 新位置 |
|---|---|---|
| HTTP 中间件 | app/Http/Kernel.php | bootstrap/app.php 的 withMiddleware() |
| 异常处理 | app/Exceptions/Handler.php | bootstrap/app.php 的 withExceptions() |
| 计划任务定义 | app/Console/Kernel.php | routes/console.php |
| 路由注册 | app/Providers/RouteServiceProvider.php | bootstrap/app.php 的 withRouting() |
| Service Provider 列表 | config/app.php 的 providers 数组 | bootstrap/providers.php |
| Policy 注册 | app/Providers/AuthServiceProvider.php | 自动注册。或在 AppServiceProvider::boot() 中手动注册 |
| 事件监听器 | app/Providers/EventServiceProvider.php | 自动注册。或在 AppServiceProvider::boot() 中手动注册 |