一.簡介
將所有的請求處理邏輯都放在單個routes.php 中肯定是不合理的,你也許還希望使用控制器類組織管理這些行為。控制器可以將相關的 HTTP 請求封裝到一個類中進行處理。通常控制器存放在app/Http/Controllers 目錄中。
二.基本控制器
1.簡單示例
下面是一個基本控制器類的例子。所有的 Laravel 控制器應該繼承自 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');
現在,如果一個請求匹配上面的路由 URI, UserController 的showProfile 方法就會被執行。當然,路由參數
也會被傳遞給這個方法。
2.控制器&命名空間
你應該注意到我們在定義控制器路由的時候沒有指定完整的控制器命名空間,而只是定義了App\Http\Controllers 之后的部分。默認情況下, RouteServiceProvider 將會在一個路由分組中載入routes.php 文件,並且該路由分組指定定了分組中路由控制器所在的命名空間。
如果你在App\Http\Controllers 目錄下選擇使用 PHP 命名空間嵌套或組織控制器,只需要使用相對於App\Http\Controllers 命名空間的指定類名即可。因此,如果你的完整控制器類是App\Http\Controllers\Photos\AdminController ,你可以像這樣注冊路由:
Route::get('foo', 'Photos\AdminController@method');
3.命名控制器路由(如果get第二個參數為字符串,則默認key為uses)
Route::get('foo', ['uses' => 'FooController@method', 'as' => 'name']);
使用action生成對應URL
$url = action('FooController@method');
還可以使用幫助函數route 來為已命名的控制器路由生成對應的 URL
$url = route('name');
4.控制器中使用中間件
$this->middleware('auth');
三.RESTful 資源控制器
1.資源控制器
使用 Artisan 命令make:controller ,我們可以快速創建一個帶有RESTful風格的控制器:
php artisan make:controller PhotoController
該 Artisan 命令將會生成一個控制器文件app/Http/Controllers/PhotoController.php ,這個控制器包含了每一個資源操作對應的方法。 接下來,可以為該控制器注冊一個資源路由:
Route::resource('photo', 'PhotoController');
這個路由聲明包含了處理圖片資源 RESTful 動作的多個路由,相應地,Artisan 生成的控制器也已經為這些動作設置了對應的處理方法。

2.定義部分資源路由
#僅僅index,show方法可用
Route::resource('photo', 'PhotoController',
['only' => ['index', 'show']]);
#除except里面的方法不可用,其余可用
Route::resource('photo', 'PhotoController',
['except' => ['create', 'store', 'update', 'destroy']]);
3.命名資源路由
默認情況下,所有資源控制器動作都有一個路由名稱,然而,我們可以通過傳入 names 數組來覆蓋這些默認的名字:
Route::resource('photo', 'PhotoController',['names' => ['create' => 'photo.build']]);
使用
route('photo.build');
即可取出對應url,如http://localhost:9000/photo/create
route/url/action的區別,
Route::resource('photo', 'PhotoController');
route('photo.index'); //如果路由有命名,可以取他的名字,如as定義的名字
url('photo');
action('PhotoController@index');
這三者取出的地址都是http://localhost:9000/photo,但每個函數的參數形式不同;
4.嵌套資源
有時候我們需要定義路由到“嵌套”資源。例如,一個圖片資源可能擁有多條“評論”,要“嵌套”資源控制器,在路由聲明中使用“.”號即可:
Route::resource('photos.comments', 'PhotoCommentController');
控制器中:
class PhotoCommentController extends Controller
{
/**
* 顯示指定照片評論
*
* @param int $photoId
* @param int $commentId
* @return Response
* @translator http://laravelacademy.org
*/
public function show($photoId, $commentId)
{
//
}
}
5.補充資源控制器
如果有必要在默認資源路由之外添加額外的路由到資源控制器,應該在調用Route::resource 之前定義這些路由;否則,通過resource 方法定義的路由可能無意中優先於補充的額外路由:
Route::get('photos/popular', 'PhotoController@method');
Route::resource('photos', 'PhotoController');
6.隱式控制器
(1).Laravel 允許你只定義一個路由即可訪問控制器類中的所有動作,首先,使用Route::controller 方法定義一個路由,該controller 方法接收兩個參數,第一個參數是控制器處理的 baseURI,第二個參數是控制器的類名:
Route::controller('users', 'UserController');
接下來,添加方法到控制器,方法名應該以 HTTP 請求方法開頭:
<?php
namespace App\Http\Controllers;
class UserController extends Controller
{
/**
* 響應 GET /users 請求
*/
public function getIndex()
{
//
}
/**
* 響應 GET /users/show/1 請求
*/
public function getShow($id)
{
//
}
/**
* 響應 GET /users/admin-profile 請求
*/
public function getAdminProfile()
{
//
}
/**
* 響應 POST /users/profile 請求
*/
public function postProfile()
{
//
}
}
在上例中可以看到, getIndex 方法將會在訪問控制器處理的默認 URI: /users 時被調用。
(2).分配路由名稱
如果你想要命名該控制器中的一些路由,可以將一個名稱數組作為第三個參數傳遞到該controller 方法:
Route::controller('users', 'UserController', [
'getShow' => 'user.show',
]);
使用route取出對應url
route('guo.show');
四.依賴注入 & 控制器
1.構造函數注入
Laravel 使用服務容器解析所有的 Laravel 控制器,因此,可以在控制器的構造函數中類型聲明任何依賴,這些依賴會被自動解析並注入到控制器實例中:
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use App\Repositories\UserRepository;
class UserController extends Controller
{
/**
* The user repository instance.
*/
protected $users;
/**
* 創建新的控制器實例
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
當然,你還可以類型提示任何 Laravel 契約,如果容器可以解析,就可以進行類型提示。
2.方法注入
<?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');
//
}
}
如果控制器方法期望輸入路由參數,只需要將路由參數放到其他依賴之后,例如,如果你的路由定義如下:
Route::put('user/{id}', 'UserController@update');
你需要通過定義控制器方法如下所示來類型提示Illuminate\Http\Request 並訪問路由參數id :
public function update(Request $request, $id)
{
//
}
四.路由緩存
1.生成路由緩存
php artisan route:cache
緩存路由文件(在bootstrap/cache/下)現在取代app/Http/routes.php 文件被使用.
因此,只有在項目運行階段你才會運行route:cache 命令
2.清除路由緩存
php artisan route:clear
