php artisan make:controller 命令不加参数仅生成空壳类;加 --invokable 生成含 __invoke() 的单动作控制器,加 --resource 自动生成 index、show 等7个标准REST方法,且方法名严格匹配路由约定,大小写敏感、不可下划线。

php artisan make:controller 命令必须加 --invokable 或 --resource 才能生成可路由的类
不加参数直接运行 php artisan make:controller UserController,生成的是空壳类,没有 index、show 等方法,也不能直接绑定到资源路由。Laravel 默认只生成类骨架,不预设逻辑。
实操建议:
- 要响应单个 URL(比如
/api/user),用--invokable:php artisan make:controller Api/UserController --invokable→ 生成带__invoke()方法的类,适合 API 端点 - 要支持完整 REST 动作(
index、store、show等),用--resource:php artisan make:controller Admin/PostController --resource→ 自动生成 7 个标准方法 - 路径中的斜杠会转为命名空间层级,
Admin/PostController会被放在app/Http/Controllers/Admin/目录下,且命名空间自动为App\Http\Controllers\Admin
控制器方法名必须和路由定义严格匹配,大小写敏感且不能带下划线
Laravel 路由解析时直接拼接方法名字符串,不会做任何转换。写成 show_user 或 ShowUser 都会报 MethodNotAllowedHttpException 或 BadMethodCallException。
常见错误现象:
- 在
routes/web.php中写了Route::get('/user/{id}', [UserController::class, 'showUser']),但控制器里方法是public function show_user()→ 找不到方法 - 用了
--resource却手动改了方法名(如把edit改成form),再用Route::resource('posts', PostController::class)→ 缺失/posts/{id}/edit路由
记住:Laravel 的资源路由约定是硬编码的,index、create、store、show、edit、update、destroy 这七个名字一个都不能错。
控制器构造函数里不能直接调用 $this->middleware(),必须在 boot() 或 __construct() 末尾注册
如果在 __construct() 开头就写 $this->middleware('auth'),中间件可能无法正确绑定到方法上,尤其在使用闭包或带 except/only 的时候。
实操建议:
- 统一把中间件注册放在
__construct()最后一行: $this->middleware('auth')->except(['index', 'show']);- 避免在构造函数中提前 return 或 throw,否则中间件注册会被跳过
- 如果控制器继承自基类(如
BaseController),确保父类__construct()不提前终止执行
Route::controller() 已废弃,别在 Laravel 8+ 里用
旧文档或老项目里可能看到 Route::controller('/users', UserController::class),它会自动映射方法名前缀(如 show → GET /users/show)。这个语法在 Laravel 8 被彻底移除,继续用会报 BadMethodCallException: Method Illuminate\Routing\Router::controller does not exist。
替代方案只有两个:
- 显式定义每条路由:
Route::get('/users', [UserController::class, 'index']) - 用
Route::resource()或Route::apiResource(),配合标准方法名
别试图用宏或服务提供者“恢复” controller() —— 它被删掉是因为隐式映射导致路由不可读、调试困难,不是遗漏。
return 就算方法执行完了也会报 500;中间件顺序错一拍,auth 可能拦不住未登录请求;资源路由的 show 方法签名必须是 show($id),不能写成 show(Request $request, $id) 再自己取参数 —— 这些细节不踩一遍,很难信。









