簡介 基礎(chǔ)控制器 控制器中間件 隱式控制器 RESTful 資源控制器 依賴注入和控制器 路由緩存
除了在單一的 routes.php
文件中定義所有的請求處理邏輯之外,你可能希望使用控制器類來組織此行為??刂破骺蓪⑾嚓P(guān)的 HTTP 請求處理邏輯組成一個類??刂破魍ǔ4娣旁?app/Http/Controllers
此目錄中。
這里是一個基礎(chǔ)控制器類的例子:
<?php namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class UserController extends Controller {
/**
* 顯示所給定的用戶個人數(shù)據(jù)。
*
* @param int $id
* @return Response
*/
public function showProfile($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
我們可以通過如下方式引導(dǎo)路由至對應(yīng)的控制器動作:
Route::get('user/{id}', 'UserController@showProfile');
注意: 所有的控制器都應(yīng)該擴(kuò)展基礎(chǔ)控制器類。
有一點(diǎn)非常重要,那就是我們無需指明完整的控制器命名空間,在類名稱中 App\Http\Controllers
之后的部分即可用于表示「根」命名空間。 RouteServiceProvider
默認(rèn)會在包含根控制器命名空間的路由群組中,加載 routes.php
此文件。
若你要在 App\Http\Controllers
此目錄深層使用 PHP 命名空間以嵌套化或組織你的控制器,只要使用相對于 App\Http\Controllers
根命名空間的特定類名稱即可。因此,若你的控制器類全名為 App\Http\Controllers\Photos\AdminController
,你可以像這樣注冊一個路由:
Route::get('foo', 'Photos\AdminController@method');
和閉包路由一樣,你也可以指定控制器路由的名稱。
Route::get('foo', ['uses' => 'FooController@method', 'as' => 'name']);
要產(chǎn)生一個指向控制器行為的 URL,可使用 action
輔助方法。
$url = action('App\Http\Controllers\FooController@method');
若你想僅使用相對于控制器命名空間的類名稱中的一部分,來產(chǎn)生指向控制器行為的 URL,可用 URL 產(chǎn)生器注冊控制器的根命名空間。
URL::setRootControllerNamespace('App\Http\Controllers');
$url = action('FooController@method');
你可以使用 currentRouteAction
方法來獲取正在執(zhí)行的控制器行為名稱:
$action = Route::currentRouteAction();
中間件 可在控制器路由中指定,例如:
Route::get('profile', [
'middleware' => 'auth',
'uses' => 'UserController@showProfile'
]);
此外,你也可以在控制器構(gòu)造器中指定中間件 :
class UserController extends Controller {
/**
* 建立一個新的 UserController 實(shí)例。
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('log', ['only' => ['fooAction', 'barAction']]);
$this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
}
}
Laravel 讓你能輕易地定義單一路由來處理控制器中的每一項行為。首先,用 Route::controller
方法定義一個路由:
Route::controller('users', 'UserController');
Controller
方法接受兩個參數(shù)。第一個參數(shù)是控制器欲處理的 base URI,第二個是控制器的類名稱。接著只要在你的控制器中加入方法,并在名稱前加上它們所對應(yīng)的 HTTP 請求。
class UserController extends BaseController {
public function getIndex()
{
//
}
public function postProfile()
{
//
}
public function anyLogin()
{
//
}
}
index
方法會響應(yīng)控制器處理的根 URI ,在這個例子中是 users
。
如果你的控制器行為包含多個字詞,你可以在 URI 中使用「破折號」語法來訪問此行為。例如,下面這個在 UserController
中的控制器動作會響應(yīng) users/admin-profile
此一 URI :
public function getAdminProfile() {}
如果你想“命名”一些控制器的路由,你可以給 controller
方法傳入第三個參數(shù):
Route::controller('users', 'UserController', [
'anyLogin' => 'user.login',
]);
資源控制器可讓你無痛建立和資源相關(guān)的 RESTful 控制器。例如,你可能希望創(chuàng)建一個控制器,它可用來處理針對你的應(yīng)用程序所保存相片的 HTTP 請求。我們可以使用 make:controller Artisan
命令,快速創(chuàng)建這樣的控制器:
php artisan make:controller PhotoController
接著,我們注冊一個指向此控制器的資源路由:
Route::resource('photo', 'PhotoController');
此單一路由聲明創(chuàng)建了多個路由,用來處理各式各樣和相片資源相關(guān)的 RESTful 行為。同樣地,產(chǎn)生的控制器已有各種和這些行為綁定的方法,包含用來通知你它們處理了那些 URI 及動詞。
動詞 | 路徑 | 行為 | 路由名稱 |
---|---|---|---|
GET | /photo | 索引 | photo.index |
GET | /photo/create | 創(chuàng)建 | photo.create |
POST | /photo | 保存 | photo.store |
GET | /photo/{photo} | 顯示 | photo.show |
GET | /photo/{photo}/edit | 編輯 | photo.edit |
PUT/PATCH | /photo/{photo} | 更新 | photo.update |
DELETE | /photo/{photo} | 刪除 | photo.destroy |
除此之外,你也可以指定讓路由僅處理一部分的行為:
Route::resource('photo', 'PhotoController',
['only' => ['index', 'show']]);
Route::resource('photo', 'PhotoController',
['except' => ['create', 'store', 'update', 'destroy']]);
所有的資源控制器行為默認(rèn)都有個路由名稱。然而你可在選項中傳遞一個 names
數(shù)組來重載這些名稱:
Route::resource('photo', 'PhotoController',
['names' => ['create' => 'photo.build']]);
在你的路由聲明中使用「點(diǎn)」號來「嵌套化」資源控制器:
Route::resource('photos.comments', 'PhotoCommentController');
此路由會注冊一個「嵌套的」資源,可透過像 photos/{photos}/comments/{comments}
這樣的 URL 來訪問。
class PhotoCommentController extends Controller {
/**
* 顯示指定照片的評論。
*
* @param int $photoId
* @param int $commentId
* @return Response
*/
public function show($photoId, $commentId)
{
//
}
}
除了默認(rèn)的資源路由外,若你還需要在資源控制器中加入其他路由,應(yīng)該在調(diào)用 Route::resource
之前先定義它們:
Route::get('photos/popular', 'PhotoController@method');
Route::resource('photos', 'PhotoController');
Laravel 服務(wù)容器 用于解析所有的 Laravel 控制器。因此,你可以在控制器所需要的構(gòu)造器中,對依賴作任何的類型限制。
<?php namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use App\Repositories\UserRepository;
class UserController extends Controller {
/**
* 用戶保存庫實(shí)例。
*/
protected $users;
/**
* 創(chuàng)建新的控制器實(shí)例。
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
當(dāng)然了,你也可以對任何的 Laravel contract 作類型限制。只要容器能解析它,你就可以對它作類型限制。
除了建構(gòu)器注入外,你也可以對控制器方法的依賴作類型限制。例如,讓我們對某個方法的 Request
實(shí)例作類型限制:
<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class UserController extends Controller {
/**
* 保存一個新的用戶。
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$name = $request->input('name');
//
}
}
如果你的控制器方法預(yù)期由路由參數(shù)取得輸入,只要在其他的依賴之后列出路由參數(shù)即可:
<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class UserController extends Controller {
/**
* 保存一個新的用戶。
*
* @param Request $request
* @param int $id
* @return Response
*/
public function update(Request $request, $id)
{
//
}
}
注意: 方法注入和 模型綁定 是完全兼容的。容器可智能地判斷那些參數(shù)和模型相關(guān)以及那些參數(shù)應(yīng)該被注入。
若您的應(yīng)用只使用了控制器路由,你可利用 Laravel 的路由緩存。使用路由緩存,將大幅降低注冊應(yīng)用程序所有路由所需要的時間。某些情況下,路由注冊甚至可以快上 100 倍。要產(chǎn)生路由緩存,只要執(zhí)行 route:cache
Artisan 命令:
php artisan route:cache
就是這樣!你的緩存路由文件將會被用來代替 app/Http/routes.php
此一文件。記住,若你增加了任何新的路由,你就 必須產(chǎn)生一個新的路由緩存。因此在應(yīng)用部署時,你可能會希望只要執(zhí)行 route:cache
命令:
要移除路由緩存文件,但不希望產(chǎn)生新的緩存,可使用 route:clear
命令:
php artisan route:clear