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