[TOC]
# 控制器
## 基础控制器
### 生成控制器
```
// 普通控制器,默认继承基础类
$ php artisan make:controller PhotoController
// 生成单个行为控制器
$ php artisan make:controller ShowProfile --invokable
// 生成资源控制器
$ php artisan make:controller PhotoController --resource
// 指定资源模型,生成时可选是否创建模型,控制器方法注入指定的模型
$ php artisan make:controller PhotoController --resource --model=Photo
// 生成API资源路由
$ php artisan make:controller Api/PhotoController --api
```
### 定义控制器
```
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* 显示给定用户的概要文件.
*
* @param int $id
* @return View
*/
public function show($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
```
>[success] 注意:控制器并不是强制要求继承基础类 。 但是如果没有继承基础类,将无法使用一些便捷的功能,比如 middleware, validate 和 dispatch 方法。
### 定义控制器路由
在路由文件定义路由,只需要指定命名空间为`App\Http\Controllers`之后的部分
```
// 定义路由
Route::get('user/{id}', 'UserController@show');
// 完整的控制器类名为 App\Http\Controllers\Photos\AdminController
Route::get('foo', 'Photos\AdminController@method');
```
### 单个行为控制器
```
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class ShowProfile extends Controller
{
/**
* 展示给定用户的资料.
*
* @param int $id
* @return View
*/
public function __invoke($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
// 路由定义,无需指明方法
Route::get('user/{id}', 'ShowProfile');
// 生成单个行为控制器
$ php artisan make:controller ShowProfile --invokable
```
## 控制器中间件
```
// 中间件可以在路由文件中分配给控制器的路由或路由组
Route::get('profile', 'UserController@show')->middleware('auth');
// 在控制器中指定中间件,使用更灵活
class UserController extends Controller
{
/**
* Instantiate a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('log')->only('index');
// 只适用 index 方法
$this->middleware('subscribed')->except('store');
// 排除 store 方法,其他都适用
}
}
// 在控制器中闭包注册中间件
,不需要注册中间件,方便单个控制器使用
public function __construct()
{
$this->middleware(function ($request, $next) {
// ...
return $next($request);
});
}
```
>[success] 提示:你可以将中间件分配给控制器操作的一个子集;但是,它可能表明你的控制器正在变得很大。建议你将控制器拆分为多个较小的控制器。
## 资源控制器
```
// 生成资源控制器
$ php artisan make:controller PhotoController --resource
// 指定资源模型,是否创建模型,控制器方法注入指定的模型
$ php artisan make:controller PhotoController --resource --model=Photo
// 定义路由
Route::resource('photos', 'PhotoController');
// 定义多个资源控制器
Route::resources([
'photos' => 'PhotoController',
'posts' => 'PostController'
]);
```
**资源路由请求方法**
HTTP 方法 | URI | 动作 | 路由名称
----------|-----------------------|--------------|---------------------
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
**表单方法伪造**
```
// PUT、PATCH、DELETE
<form action="/foo/bar" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
<form action="/foo/bar" method="POST">
@method('PUT')
@csrf
</form>
```
### 部分资源路由
```
// 指定控制器需要处理的部分行为
Route::resource('photos', 'PhotoController')->only([
'index', 'show'
]);
Route::resource('photos', 'PhotoController')->except([
'create', 'store', 'update', 'destroy'
]);
```
### API资源路由
>[success] 排除 create 和 edit 显示 HTML 模板的路由
```
// 生成API资源路由
$ php artisan make:controller Api/PhotoController --api
Route::apiResource('photos', 'PhotoController');
Route::apiResources([
'photos' => 'PhotoController',
'posts' => 'PostController'
]);
```
### 重命名路由方法
```
Route::resource('photos', 'PhotoController')->names([
'create' => 'photos.build'
]);
// 设置所有资源路由的前缀
Route::resource('photos', 'PhotoController', ['names' => 'admin.photos']);
```
### 重命名路由参数
```
// 生成路由uri为 /users/{admin_user}
Route::resource('users', 'AdminUserController')->parameters([
'users' => 'admin_user'
]);
```
### 全局重命名路由方法
```
// 在 AppServiceProvider 的 boot 方法中使用 Route::resourceVerbs 方法实现
use Illuminate\Support\Facades\Route;
/**
* 初始化任何应用服务
*
* @return void
*/
public function boot()
{
Route::resourceVerbs([
'create' => 'crear',
'edit' => 'editar',
]);
}
// 生成路由uri
/fotos/crear
/fotos/{foto}/editar
```
### 定义默认方法以外的路由
>[success] 为资源控制器添加默认路由之外的额外路由,需要在 Route::resource 之前定义
```
Route::get('photos/popular', 'PhotoController@method');
Route::resource('photos', 'PhotoController');
```
## 依赖注入 & 控制器
### 构造函数注入
```
<?php
namespace App\Http\Controllers;
use App\Repositories\UserRepository;
class UserController extends Controller
{
/**
* The user repository instance.
*/
protected $users;
/**
* Create a new controller instance.
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
```
### 方法注入
```
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* Store a new user.
*
* @param Request $request
* @return Response
*/
public function store(Request $request, $id)
{
$name = $request->name;
//
}
}
```
>[success] 路由参数放在这些依赖项的后面
- 入门指南
- 安装
- 部署
- 基础功能
- 路由
- 中间件
- CSRF 保护
- 控制器
- 请求
- 响应
- 视图
- URL
- Session
- 表单验证
- 错误
- 日志
- 前端开发
- Blade 模板
- 本地化
- 脚手架
- 编译资源 Mix
- 安全相关
- 用户认证
- API 认证
- 综合话题
- 命令行
- 广播
- 缓存
- 集合
- 事件
- 文件存储
- 辅助函数
- 邮件发送
- 消息通知
- 扩展包开发
- 队列
- 任务调度
- 数据库
- 快速入门
- 查询构造器
- 分页
- 数据库迁移
- 数据填充
- Redis
- Eloquent ORM
- 快速入门
- 速查表
- Artisan
- Auth
- Blade
- Cache
- Collection
- Composer
- Config
- Container
- Cookie
- DB
- Environment
- Event
- File
- Helper
- Input
- Lang
- Log
- Model
- Pagination
- Queue
- Redirect
- Request
- Response
- Route
- SSH
- Schema
- Security
- Session
- Storage
- String
- URL
- UnitTest
- Validation
- View