前言:之前在学习并使用 Laravel 框架过程中,全是碎片化掌握,现在重新学习并记录一次学习的过程。
本文内容对应 Laravel8.* 版本。
直达入口:
怎么理解 MVC ,请看 MVC与三层架构理解。
前边的系统,所有的请求都转发到路由闭包中处理了,那实际项目中,不能啥也往路由闭包中写吧。
这时就可以使用 控制器类了。控制器类存放在 app/Http/Controllers 目录。
一、基础控制器
1.1 artisan 命令生成控制器
Artisan 命令生成的控制器,默认保存在 app/Http/Controllers 目录。
php artisan make:controller UserController
默认继承 Laravel 的基础控制器。
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\User;
class UserController extends Controller
{
public function show($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
1.2 单行为控制器
什么是单行为控制器?就是只处理单个行为的控制器。
使用 Artisan 命令时追加 --invokable 选项,即可创建单行为控制器。
php artisan make:controller AboutController --invokable
在控制器中只有 __invoke 方法。
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\User;
class AboutController extends Controller
{
public function __invoke($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
定义单个行为控制器的路由时不需要指定方法就会自动调用 __invoke 方法。
use App\Http\Controllers\AboutController;
Route::get('user/{id}', AboutController::class);
二、 控制器中间件
2.1 分配给控制器的路由中间件
Route::get('profile', [UserController::class, 'show'])->middleware('auth');
2.2 构造函数中间件
将中间件调用放到控制器的构造函数当中。
class UserController extends Controller
{
public function __construct()
{
$this->middleware('auth');
$this->middleware('log')->only('index');
$this->middleware('subscribed')->except('store');
}
}
同时,控制器还允许使用中间件闭包。
$this->middleware(function ($request, $next) {
return $next($request);
});
三、资源控制器
啥是资源路由:Laravel 的资源路由可通过单行代码将典型的「CURD增删改查」路由分配给控制器。
啥是资源控制器:通过 artisan 命令生成资源控制器,控制器中包括每个可用资源的操作方法。接着往下看,你就知道了。
3.1 生成资源控制器
php artisan make:controller PhotoController --resource
php artisan make:controller API/PhotoController --api
生成后,去 app/Http/Controllers 目录找到该控制器,查看控制器内的操作方法。
3.2 生成资源控制器路由
使用 resource 注册资源控制器路由
Route::resource('photos', PhotoController::class);
Route::resources([
'photos' => PhotoController::class,
'videos' => VideoController::class
]);
3.3 生成 API 资源控制器路由
使用 api 路由时,通常会屏蔽显示模板的路由(如 create 和 edit),使用 apiResource 会自动屏蔽。
Route::apiResource('photos', PhotoController::class);
Route::apiResource([
'photos' => PhotoController::class,
'videos' => VideoController::class
]);
3.4 资源控制器操作处理表
结合刚生成的控制器类的文件内容,对应查看,就明白啥意思了
Verb | URI | Action | Route Name |
---|
GET | /photos | index | photos.index | GET | /photos/create | create | photos.create | POST | /photos | store | photos.store | GET | /photos/{photo} | show | photos.show | GET | /photos/{photo}/edit | edit | photos.edit | PUT/PATCH | /photos/{photo} | update | photos.update | DELETE | /photos/{photo} | destroy | photos.destroy |
3.5 指定资源模型
如果你使用了路由模型绑定,并且想在资源控制器中使用类型提示,那么在生成控制器时,指定模型即可。
php artisan make:controller VideoController --resource --model=Video
指定模型绑定后,执行生成命令,如果模型类不存在,则会提示是是否创建,输入 yes 即可创建。
默认的默认类存在在 app/Http/Models/ 目录中。
3.6 部分资源路由
资源路由,默认处理资源控制器中的所有行为,通过 only 方法可以处理部分行为。
Route::resource('photos', PhotoController::class)->only([
'index', 'show'
]);
Route::resource('photos', PhotoController::class)->except([
'create', 'store', 'update'
]);
3.7 嵌套资源
有时可能需要一个嵌套的资源型路由。比如,照片资源可能添加了多个评论,那么在路由中就可以使用 「点 .」符号来声明资源型路由。
Route::resource('photos.comments', PhotoCommentController::class);
该路由会注册一个嵌套资源,访问 URI 是:
/photos/{photo}/comments/{comment}
3.8 命名资源路由
默认情况下,所有资源控制器会生成默认的路由名称,如 create、update 等,但你可以链式调用 names 方法,传入名称数组来替换这些默认的路由名称。
Route::resource('photos', PhotoController::class)->names([
'create' => 'photos.build'
]);
3.9 命令资源路由参数
Laravel 默认情况下,会按资源名的「单数」形式创建资源路由的参数。但你可以链式调用 parameters 方法,传入参数名称数组,覆盖默认的参数资源。
Route::resource('users', AdminUserController::class)->parameters([
'users' => 'admin_user'
]);
四、依赖流入 & 控制器
4.1 构造函数注入
构造函数注入就是可以在控制器的构造函数中使用类型提示,来传入需要的依赖项。
<?php
namespace App\Http\Controllers;
use App\Repositories\UserRepository;
class UserController extends Controller
{
protected $users;
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
4.2 方法注入
方法注入类似于构造函数注入。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function store(Request $request)
{
$name = $request->name;
}
}
五、路由缓存
如果项目仅使用了基于路由的控制器,你应该利用 Laravel 的路由缓存。
php artisan route:cache
php artisan route:clear
|