將所有的請求處理邏輯都放在單個routes.php
中肯定是不合理的,你也許還希望使用控制器請求封裝到一個類中進(jìn)行處理。通??刂破鞔娣旁?code>app/Http/Controllers目錄中。
下面是一個基本控制器類的例子。所有的Laravel控制器應(yīng)該繼承自Laravel自帶的控制器基類Controller
:
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* 為指定用戶顯示詳情
*
* @param int $id
* @return Response
*/
public function showProfile($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
我們可以像這樣定義指向該控制器動作的路由:
Route::get('user/{id}', 'UserController@showProfile');
現(xiàn)在,如果一個請求匹配上面的路由URI,UserController
的showProfile
方法就會被執(zhí)行。當(dāng)然,路由參數(shù)也會被傳遞給這個方法。
你應(yīng)該注意到我們在定義控制器路由的時候沒有指定完整的控制器命名空間,而只是定義了App\Http\Controllers
之后的部分。默認(rèn)情況下,RouteServiceProvider
將會在一個路由分組中載入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']);
設(shè)置好控制器路由后,就可以使用幫助函數(shù)action
很方便地為控制器動作生成對應(yīng)的URL:
$url = action('FooController@method');
你還可以使用幫助函數(shù)route
來為已命名的控制器路由生成對應(yīng)的URL:
$url = route('name');
中間件可以像這樣分配給控制器路由:
Route::get('profile', [
'middleware' => 'auth',
'uses' => 'UserController@showProfile'
]);
但是,將中間件放在控制器構(gòu)造函數(shù)中更方便,在控制器的構(gòu)造函數(shù)中使用middleware
方法你可以很輕松的分配中間件給該控制器。你甚至可以限定該中間件應(yīng)用到該控制器類的指定方法:
class UserController extends Controller
{
/**
* 實(shí)例化一個新的 UserController 實(shí)例
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('log', ['only' => ['fooAction', 'barAction']]);
$this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
}
}
Laravel的資源控制器使得構(gòu)建圍繞資源的RESTful控制器變得毫無痛苦,例如,你可能想要在應(yīng)用中創(chuàng)建一個控制器,用于處理關(guān)于圖片存儲的HTTP請求,使用Artisan命令make:controller
,我們可以快速創(chuàng)建這樣的控制器:
php artisan make:controller PhotoController
該Artisan命令將會生成一個控制器文件app/Http/Controllers/PhotoController.php
,這個控制器包含了每一個資源操作對應(yīng)的方法。
接下來,可以為該控制器注冊一個資源路由:
Route::resource('photo', 'PhotoController');
這個路由聲明包含了處理圖片資源RESTful動作的多個路由,相應(yīng)地,Artisan生成的控制器也已經(jīng)為這些動作設(shè)置了對應(yīng)的處理方法。
方法 | 路徑 | 動作 | 路由名稱 |
---|---|---|---|
GET | /photo |
index | photo.index |
GET | /photo/create |
create | photo.create |
POST | /photo |
store | photo.store |
GET | /photo/{photo} |
show | photo.show |
GET | /photo/{photo}/edit |
edit | photo.edit |
PUT/PATCH | /photo/{photo} |
update | photo.update |
DELETE | /photo/{photo} |
destroy | photo.destroy |
聲明資源路由時可以指定該路由處理的動作子集:
Route::resource('photo', 'PhotoController',
['only' => ['index', 'show']]);
Route::resource('photo', 'PhotoController',
['except' => ['create', 'store', 'update', 'destroy']]);
默認(rèn)情況下,所有資源控制器動作都有一個路由名稱,然而,我們可以通過傳入names
數(shù)組來覆蓋這些默認(rèn)的名字:
Route::resource('photo', 'PhotoController',
['names' => ['create' => 'photo.build']]);
有時候我們需要定義路由到“嵌套”資源。例如,一個圖片資源可能擁有多條“評論”,要“嵌套”資源控制器,在路由聲明中使用“.”號即可:
Route::resource('photos.comments', 'PhotoCommentController');
該路由將注冊一個嵌套的資源,使用URL訪問方式如下:photos/{photos}/comments/{comments}
.
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class PhotoCommentController extends Controller
{
/**
* 顯示指定照片評論
*
* @param int $photoId
* @param int $commentId
* @return Response
* @translator http://laravelacademy.org
*/
public function show($photoId, $commentId)
{
//
}
}
如果有必要在默認(rèn)資源路由之外添加額外的路由到資源控制器,應(yīng)該在調(diào)用Route::resource
之前定義這些路由;否則,通過resource
方法定義的路由可能無意中優(yōu)先于補(bǔ)充的額外路由:
Route::get('photos/popular', 'PhotoController@method');
Route::resource('photos', 'PhotoController');
擴(kuò)展閱讀:實(shí)例教程——創(chuàng)建RESTFul風(fēng)格控制器實(shí)現(xiàn)文章增刪改查
Laravel允許你只定義一個路由即可訪問控制器類中的所有動作,首先,使用Route::controller
方法定義一個路由,該controller
方法接收兩個參數(shù),第一個參數(shù)是控制器處理的baseURI,第二個參數(shù)是控制器的類名:
Route::controller('users', 'UserController');
接下來,添加方法到控制器,方法名應(yīng)該以HTTP請求方法開頭:
<?php
namespace App\Http\Controllers;
class UserController extends Controller
{
/**
* 響應(yīng) GET /users 請求
*/
public function getIndex()
{
//
}
/**
* 響應(yīng) GET /users/show/1 請求
*/
public function getShow($id)
{
//
}
/**
* 響應(yīng) GET /users/admin-profile 請求
*/
public function getAdminProfile()
{
//
}
/**
* 響應(yīng) POST /users/profile 請求
*/
public function postProfile()
{
//
}
}
在上例中可以看到,getIndex
方法將會在訪問控制器處理的默認(rèn)URI——users時被調(diào)用。
如果你想要命名該控制器中的一些路由,可以將一個名稱數(shù)組作為第三個參數(shù)傳遞到該controller
方法:
Route::controller('users', 'UserController', [
'getShow' => 'user.show',
]);
Laravel使用服務(wù)容器解析所有的Laravel控制器,因此,可以在控制器的構(gòu)造函數(shù)中類型聲明任何依賴,這些依賴會被自動解析并注入到控制器實(shí)例中:
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use App\Repositories\UserRepository;
class UserController extends Controller
{
/**
* The user repository instance.
*/
protected $users;
/**
* 創(chuàng)建新的控制器實(shí)例
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
當(dāng)然,你還可以類型提示任何Laravel契約,如果容器可以解析,就可以進(jìn)行類型提示。
除了構(gòu)造函數(shù)注入之外,還可以在控制器的動作方法中進(jìn)行依賴的類型提示,例如,我們可以在某個方法中類型提示Illuminate\Http\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');
//
}
}
如果控制器方法期望輸入路由參數(shù),只需要將路由參數(shù)放到其他依賴之后,例如,如果你的路由定義如下:
Route::put('user/{id}', 'UserController@update');
你需要通過定義控制器方法如下所示來類型提示Illuminate\Http\Request
并訪問路由參數(shù)id
:
<?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
* @translator http://laravelacademy.org
*/
public function update(Request $request, $id)
{
//
}
}
如果你的應(yīng)用完全基于路由使用控制器,可以使用Laravel的路由緩存,使用路由緩存將會極大減少注冊所有應(yīng)用路由所花費(fèi)的時間開銷,在某些案例中,路由注冊速度甚至能提高100倍!想要生成路由緩存,只需執(zhí)行Artisan命令route:cache
:
php artisan route:cache
就這么簡單!你的緩存路由文件現(xiàn)在取代app/Http/routes.php
文件被使用,記住,如果你添加新的路由需要重新生成路由緩存。因此,只有在項(xiàng)目開發(fā)階段你才會運(yùn)行route:cache
命令。
想要移除緩存路由文件,使用route:clear
命令即可:
php artisan route:clear
更多建議: