必须重写 bootstrap/app.php 并清理 config/app.php 中的冗余服务提供者声明,否则 Laravel 11 启动失败;withProviders() 必须在 withRouting() 之前调用,中间件需迁移至 withMiddleware() 闭包,register() 中的 bind 应改为 extend。

将 Laravel 10 项目中的服务提供者结构适配到 Laravel 11 的新启动模型,必须重写 bootstrap/app.php 并清理 config/app.php 中的冗余注册项,否则容器会报 Provider already registered 或直接拒绝启动。
重写 bootstrap/app.php 启动文件
这一步不可跳过,Laravel 11 将所有启动逻辑收口至此,旧版分散在 app/Providers/RouteServiceProvider.php 和 app/Http/Kernel.php 的配置全部失效。
打开 bootstrap/app.php,用以下模板完全替换原有内容:
use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Config;
use App\Providers\AppServiceProvider;
// 若你有其他自定义服务提供者,如 AuthServiceProvider、EventServiceProvider,也在此处 use
return Application::configure(basePath: dirname(__DIR__))
->withProviders()
->withRouting()
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [EnsureEmailIsVerified::class]);
})
->withExceptions(function (Exceptions $exceptions) {
// 异常处理逻辑保持原样即可
});
【withProviders() 必须放在 withRouting() 之前】,否则 RouteServiceProvider 中的 boot() 方法无法访问已注册的服务,路由加载会失败并静默返回空响应。
清理 config/app.php 中的手动服务提供者声明
Laravel 11 默认自动注册 AppServiceProvider、AuthServiceProvider、EventServiceProvider 等核心提供者,重复声明会导致启动报错。
打开 config/app.php,找到 'providers' 数组,删除所有以 App\Providers\ 开头的类名条目,例如:
'providers' => [
// 删除这一行 → App\Providers\AppServiceProvider::class,
// 删除这一行 → App\Providers\AuthServiceProvider::class,
// 删除这一行 → App\Providers\EventServiceProvider::class,
],
只保留第三方包的服务提供者,比如 laravel/sanctum 的 SanctumServiceProvider、spatie/laravel-ignition 的 IgnitionServiceProvider。
如果项目中曾手动添加过自定义提供者(如 App\Providers\CustomLoggingServiceProvider),请确认它是否已被 withProviders() 自动发现——默认只扫描 App\Providers\ 下的类;若不在该命名空间,需显式传入:->withProviders([App\Providers\CustomLoggingServiceProvider::class])。
迁移中间件注册逻辑
中间件不再通过 app/Http/Kernel.php 注册,而是统一由 bootstrap/app.php 的 withMiddleware() 闭包管理。旧文件会被 php artisan upgrade 自动删除,但你的中间件类本身仍有效。
第一步:确认中间件类路径未变,比如 app/Http/Middleware/EnsureEmailIsVerified.php 依然存在且命名空间正确。
第二步:将原来 Kernel.php 中 $middleware、$middlewareGroups、$routeMiddleware 里的定义,逐条迁移到 bootstrap/app.php 的 withMiddleware() 闭包内:
→ web 组追加中间件:$middleware->web(append: [EnsureEmailIsVerified::class]);
→ api 组替换中间件:$middleware->api(replace: [ThrottleRequests::class]);
→ 全局中间件:$middleware->appendToGroup('web', TrimStrings::class);
注意:Laravel 11 移除了 $middlewareGroups 键,旧版 'api' => [...] 定义方式已无效,必须用 ->api() 方法重写;漏掉这步会导致 API 路由完全不经过限流或 CORS 中间件。
适配 AppServiceProvider 的 register() 方法
register() 方法签名虽未变,但容器绑定机制已重构:Laravel 11 推荐使用扩展而非直接 bind,尤其对单例和上下文感知绑定。
方法一:传统 bind 替换为 extend(推荐)
public function register()
{
$this->app->extend('cache', function ($cache, $app) {
return new CustomCacheAdapter($cache);
});
}
方法二:改用容器扩展语法(更安全)
$this->app->extend('db', function ($db, $app) {
return new CustomConnection($db);
});
方法三:若你依赖 Illuminate\Support\ServiceProvider 的原始 bind 行为,请确认绑定时机——register() 中不能调用 $this->app->make(),否则会触发循环解析;必须改用 defer() 或延迟到 boot() 中执行。
这一步操作起来很简单,直接把旧 bind 改成 extend 就行,但不改会导致某些服务在 resolve 时返回 null 而不是预期实例。


















