介绍
不要把所有处理请求的逻辑都放到一个单独的 routes.php 文件里,我们可以使用控制器去组织这些行为。Controller 可以把相关的处理 HTTP 请求的逻辑放到一个类里面。一般控制器都放在 app/Http/Controllers 这个目录的下面:
app/Http/Controllers ├── Auth │ ├── AuthController.php │ └── PasswordController.php ├── Controller.php ├── HomeController.php └── WelcomeController.php 1 directory, 5 files
基本的控制器
下面是一个基本的控制器类:
<?php namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class UserController extends Controller {
/**
* Show the profile for the given user.
*
* @param int $id
* @return Response
*/
public function showProfile($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
上面定义了一个叫 UserController 的控制器,在这个控制器里有一个方法叫 showProfile,我们可以在路由里使用这个控制器里的这个方法,像这样:
Route::get('user/{id}', 'UserController@showProfile');
这样当用户请求访问 user/{id} 这种类型的地址的时候,就会用 UserController 里面的 showProfile 这个方法来处理这些请求。
注意:所有的控制器都要去继承 BaseController 这个类。
控制器与命名空间
使用控制器的时候,不需要去指定控制器的全部命名空间,可以只用在 App\Http\Controllers(命名空间的根) 命名空间之后的部分。默认情况下,RouteServiceProvider 在载入 routes.php 文件的时候,会包含控制器命名空间的根。
如果你选择嵌套或者使用 PHP 命名空间组织的控制器深于 App\Http\Controllers 目录,可以简单的使用相对于 App\Http\Controllers 这个根命名空间的类名。也就是,如果你的控制器是 App\Http\Controllers\Photos\Administrator,你可以像这样去注册一个路由:
Route::get('foo', 'Photos\AdminController@method');
命名控制器路由
跟 Closure 路由一样,你也可以为控制器路由起个名字:
Route::get('foo', ['uses' => 'FooController@method', 'as' => 'name']);
控制器动作的地址
生成一个到控制器动作的 URL ,可以使用 action 这个帮手方法:
$url = action('App\Http\Controllers\FooController@method');
在只用相对于控制器命名空间根的类名的一部分去生成一个到控制器动作的 URL 的时候,可以用 URL 生成器先注册一下控制器命名空间的根:
URL::setRootControllerNamespace('App\Http\Controllers'); $url = action('FooController@method');
使用 currentRouteAction 方法,可以访问到运行的控制器动作的名字:
$action = Route::currentRouteAction();
控制器中间件
在控制器路由上使用中间件,可以像这样:
Route::get('profile', [ 'middleware' => 'auth', 'uses' => 'UserController@showProfile' ]);
另外,你可以在控制器的构造函数(Constructor)里指定中间件:
class UserController extends Controller {
/**
* Instantiate a new UserController instance.
*/
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 这个方法接受两个参数。第一个参数是控制器处理的基本的 URI ,第二个是控制器的类的名字。然后,在控制器里添加方法的时候,要使用 HTTP 动作(get,post,put,delete)作为这些方法的前缀:
class UserController extends BaseController { public function getIndex() { // } public function postProfile() { // } public function anyLogin() { // } }
index 方法可以处理对控制器的根地址的请求,这里就是 users 这个地址。
如果你的控制器的动作里面包含多个词,访问这样的动作,可以在地址里可以使用横线( - )的形式。比如下面这个在 UserController 控制器里的 getAdminProfile 这个方法,处理的是来自 users/admin-profile 这个地址的请求:
public function getAdminProfile() {}
RESTful 资源控制器
围绕着网站上的资源去创建 RESTful 类型的控制器,可以使用 Resource 类型控制器,这样更简单一些。比如,你可能想要为网站上的 photos(图片)创建控制器来处理 HTTP 的请求。使用 make:controller 这个 Artisan 命令可以快速的创建这样的控制器:
php arisan make:controller PhotoController
然后,再用一个资源类型的路由去使用在上面创建的这个资源控制器:
Route::resource('photo', 'PhotoController');
上面这个路由创建了多个路由,去处理在 photo 资源上的不同的 RESTful 动作。同样用命令生成的这个资源控制器里面也会有处理这些动作的方法,上面有说明,告诉你处理的是哪种地址还有动作。
资源控制器处理的动作
HTTP 动作 | 路径 | 动作 | 路由的名字 |
---|---|---|---|
GET | /resource | index | resource.index |
GET | /resource/create | create | resource.create |
POST | /resource | store | resource.store |
GET | /resource/{resource} | show | resource.show |
GET | /resource/{resource}/edit | edit | resource.edit |
PUT/PATCH | /resource/{resource} | update | resource.update |
DELETE | /resource/{resource} | destroy | resource.destroy |
自定义资源路由
你可以在路由上指定一部分动作来处理:
Route::resource('photo', 'PhotoController', ['only' => ['index', 'show']]); Route::resource('photo', 'PhotoController', ['except' => ['create', 'store', 'update', 'destroy']]);
在默认情况下,所有的资源控制器的动作都有一个路由的名字,不过你可以使用 names 数组覆盖掉这些名字:
Route::resource('photo', 'PhotoController', ['names' => ['create' => 'photo.build']]);
处理嵌套的资源控制器
在定义路由的时候,用点的形式(dot notation)来使用嵌套的资源控制器:
Route::resource('photos.comments', 'PhotoCommentController');
上面这个路由注册了一个嵌套的资源,访问它的时候,这个地址看起来像这样:photos/{photos}/comments/{comments}
class PhotoCommentController extends Controller { /** * Show the specified photo comment. * * @param int $photoId * @param int $commentId * @return Response */ public function show($photoId, $commentId) { // } }
在资源控制器里添加额外的路由
如果必须要在资源控制器里添加额外的路由,需要在调用 Route::resource 之前去定义它们:
Route::get('photos/popular'); Route::resource('photos', 'PhotoController');
依赖注入与控制器
这部分内容会在以后补上:)
路由缓存
如果你在网站上只用控制器路由,你可以使用 Laravel 的路由缓存。使用路由缓存可以很大程序的减少注册所有网站所有的路由所用的时间。在有些情况下,可以快一百倍。生成路由缓存,只需要使用 route:cache 这个 Artisan 命令:
php artisan route:cache
完成以后,就会使用路由缓存来代替 app/Http/routes.php 文件。注意如果你添加了新的路由,你需要生成新的路由缓存,因为这个,只在部署项目的时候才会使用 route:cache 命令。
想要删除掉路由缓存,可以使用 route:clear 命令:
php artisan route:clearLaravel Laravel5 控制器 Controller 中文手册