laravel 11 路由机制重构导致旧代码404等问题:必须删除 web.php/api.php、新建 routes.php 并显式引入;中间件组需在 bootstrap/app.php 中注册;本地化路由须用 route::localized() 包裹;post 验证失败需显式处理否则误跳 show 方法。

在 Laravel 11 中访问原本为 Laravel 8 编写的路由代码时,页面直接 404、重定向错乱、中间件不生效或 POST 请求跳转到 show 方法,不是配置遗漏,而是框架路由加载机制与执行链已被结构性重写——旧写法在新版本里根本不会被识别。
路由文件结构已强制扁平化
第一步:删除 routes/web.php 和 routes/api.php 两个文件;
第二步:在 routes/ 目录下新建 routes.php,以 use Illuminate\Support\Facades\Route; 开头;
第三步:把原 web.php 中所有路由用 Route::middleware('web')->group() 包裹,原 api.php 中所有路由改用 Route::middleware('api')->group() 包裹;
第四步:在 routes.php 中显式 require 这两段逻辑,例如:require __DIR__.'/web.php'; 和 require __DIR__.'/api.php';。
这一步不可跳过。Laravel 11 默认只加载 routes.php,【routes/web.php 和 routes/api.php 不再自动扫描】,哪怕文件存在也完全静默忽略。
中间件组注册方式彻底变更
方法一:在 bootstrap/app.php 的 ->withMiddleware() 闭包中声明 web 和 api 组:
$middleware->web(append: [\App\Http\Middleware\EncryptCookies::class]);$middleware->api(prepend: [\Illuminate\Routing\Middleware\SubstituteBindings::class]);
方法二:若沿用旧版 app/Http/Kernel.php,必须清空全部 $middlewareGroups 和 $middleware 属性——它们在 Laravel 11 中已被完全弃用,残留会导致中间件组无法识别,报错 Middleware group [web] does not exist。
注意:Route::prefix('api') 不再自动挂载 api 中间件组,漏写 ->middleware('api') 就会跳过 CORS、认证、CSRF 等关键校验,POST 请求可能直接 405 或 419。
本地化路由必须显式包裹
Laravel 8 中可用 mcamara/laravel-localization 的 LaravelLocalizationRoutes 中间件解析 /zh/profiles 路由;Laravel 11 要求所有多语言路由必须使用 Route::localized() 宏包裹,否则语言前缀不生效,且 fallback 到默认语言时 URL 会丢失路径参数。
例如,原写法:Route::get('/profiles', [ProfileController::class, 'index'])->name('profiles');
必须改为:
Route::localized(function () {<br> Route::get('/profiles', [ProfileController::class, 'index'])->name('profiles');<br>});
【未用 Route::localized() 包裹的本地化路由,在 Laravel 11 中将无法匹配任何带语言前缀的请求】,浏览器访问 /zh/profiles 会直接 404。
POST 表单跳转到 show 方法的根因
这不是路由定义问题,而是验证失败后“回退”机制失效导致的连锁反应:Laravel 8 允许 FormRequest 验证失败后自动 back() 并保留输入,Laravel 11 默认关闭该行为,且要求验证失败必须返回明确响应(如 redirect()->withErrors()),否则请求中断后框架尝试匹配上一个 GET 路由——恰好是 /{id},触发隐式模型绑定并调用 show()。
修复方式:在控制器 update 方法中,不依赖隐式回退,改用显式错误处理:
if ($request->fails()) {<br> return redirect()->back()->withErrors($request->errors())->withInput();<br>}
或者直接在 FormRequest 的 rules() 中确保只校验表单实际提交的字段,避免验证未提交字段(如 password、email)导致静默失败。











