[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