控制器是 Laravel 应用的核心组成部分,负责接收用户请求、调用业务逻辑并返回响应。 本章将带你从零开始学习控制器的基本概念、创建方法以及与路由的协作方式。
在 Laravel 中,控制器是存放业务逻辑的类,通常位于 app/Http/Controllers 目录下。
它将路由闭包中的代码集中管理,让代码结构更清晰、易于维护和测试。
使用 Artisan 命令 make:controller 可以快速生成控制器文件:
php artisan make:controller UserController
该命令会在 app/Http/Controllers 目录下创建 UserController.php 文件,内容如下:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
//
}
Controller 基类以使用一些辅助方法(如 authorize 等)。
在控制器中添加公共方法,每个方法对应一个路由的处理逻辑。例如:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
return view('users.index', ['users' => User::all()]);
}
public function show($id)
{
return view('users.show', ['user' => User::findOrFail($id)]);
}
}
在 routes/web.php 中,将 URI 指向控制器的特定方法:
use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);
如果项目中大量使用控制器,可以通过路由分组指定命名空间:
Route::namespace('App\Http\Controllers')->group(function () {
Route::get('/users', 'UserController@index');
// 注意:Laravel 11 中不推荐这种写法,推荐使用 ::class 方式,更利于 IDE 支持。
});
Laravel 的服务容器可以自动解析控制器方法中的类型提示,实现依赖注入:
use Illuminate\Http\Request;
use App\Services\UserService;
class UserController extends Controller
{
// 注入 Request 对象
public function store(Request $request)
{
// $request->all() 获取所有输入
}
// 注入自定义服务类
public function index(UserService $userService)
{
$users = $userService->getAllUsers();
return view('users.index', compact('users'));
}
}
public function update(Request $request, $id)。
如果控制器只负责一个动作,可以使用 __invoke 方法创建“单动作控制器”:
php artisan make:controller ShowProfileController --invokable
生成的控制器:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ShowProfileController extends Controller
{
public function __invoke(Request $request)
{
// 单个方法逻辑
return view('profile.show');
}
}
路由绑定方式:Route::get('/profile', ShowProfileController::class);
可以在控制器构造函数中指定中间件,或直接在路由中绑定:
class UserController extends Controller
{
public function __construct()
{
// 为控制器中所有方法应用中间件
$this->middleware('auth');
// 仅为特定方法应用中间件
$this->middleware('admin')->only(['edit', 'update', 'destroy']);
// 排除某些方法
$this->middleware('log')->except(['index', 'show']);
}
}
使用 Route::resource 可以快速生成符合 RESTful 规范的路由:
Route::resource('photos', PhotoController::class);
此时控制器需要包含以下方法:index, create, store, show, edit, update, destroy。
可以使用 --resource 选项生成带这些方法的控制器:
php artisan make:controller PhotoController --resource
以下是一个完整的控制器示例,展示了增删改查的基本操作:
@verbatim<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
// 列表
public function index()
{
$posts = Post::latest()->paginate(10);
return view('posts.index', compact('posts'));
}
// 创建表单
public function create()
{
return view('posts.create');
}
// 保存
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|max:255',
'content' => 'required',
]);
Post::create($validated);
return redirect()->route('posts.index')->with('success', '文章创建成功!');
}
// 显示单篇文章
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
// 编辑表单
public function edit(Post $post)
{
return view('posts.edit', compact('post'));
}
// 更新
public function update(Request $request, Post $post)
{
$validated = $request->validate([
'title' => 'required|max:255',
'content' => 'required',
]);
$post->update($validated);
return redirect()->route('posts.show', $post)->with('success', '文章更新成功!');
}
// 删除
public function destroy(Post $post)
{
$post->delete();
return redirect()->route('posts.index')->with('success', '文章已删除!');
}
}
show(Post $post))会自动根据路由参数获取模型,如果未找到会自动返回 404。确保路由参数名称与变量名一致(如 {post})。
app() 辅助函数,优先通过类型提示注入依赖。/post/{post},控制器方法为 show(Post $post)。
response()->json() 返回 JSON 数据。如果同时需要支持 Web 和 API,通常将 API 逻辑放在单独的控制器目录(如 Api)中。
App\Http\Controllers\UserController::class)或通过 use 导入。原来的 RouteServiceProvider 中不再默认设置 namespace。
控制器是 Laravel 应用的核心组织单元。通过 Artisan 命令可以快速生成控制器,并与路由绑定处理各种请求。 掌握依赖注入、中间件、资源路由等技巧,能够让你构建出结构清晰、易于维护的应用。 下一章我们将深入学习控制器的依赖注入与请求处理。