与其把所有路由逻辑写在一个 routes.php
文件中,你也许更希望用控制器类来组织它们。控制器可以把相关的路由逻辑组织在一个类中,而且可以使用由框架提供的更为强大的功能,比如自动依赖注入。
控制器一般储存在 app/controllers
目录下,这个目录默认已经被注册在 composer.json
文件的 classmap
属性中。
这是一个基础控制器的例子:
class UserController extends BaseController {
/**
* Show the profile for the given user.
*/
public function showProfile($id)
{
$user = User::find($id);
return View::make('user.profile', array('user' => $user));
}
}
所有控制器需要继承 BaseController
类。 BaseController
类也储存在 app/controllers
下,通常用来放置公用的控制器逻辑。 BaseController
类继承自框架的 Controller
类。现在,你可以在路由中像这样调用控制器操作:
Route::get('user/{id}', 'UserController@showProfile');
如果你需要使用PHP命名空间嵌套组织控制器,你可以在定义路由时使用类名的全称:
Route::get('foo', 'Namespace\FooController@method');
你也可以在控制器路由中指定名称:
Route::get('foo', array('uses' => 'FooController@method',
'as' => 'name'));
你可以使用 URL::action
方法获取一个控制器操作的链接:
$url = URL::action('FooController@method');
你可以使用 currentRouteAction
方法获取当前控制器操作的名称:
$action = Route::currentRouteAction();
过滤器可以在控制器路由中指定,就像这样一个"标准的"路由:
Route::get('profile', array('before' => 'auth',
'uses' => 'UserController@showProfile'));
不过,你也可以在控制器内部指定过滤器:
class UserController extends BaseController {
/**
* Instantiate a new UserController instance.
*/
public function __construct()
{
$this->beforeFilter('auth');
$this->beforeFilter('csrf', array('on' => 'post'));
$this->afterFilter('log', array('only' =>
array('fooAction', 'barAction')));
}
}
你也可以使用闭包来指定内联的控制器过滤器:
class UserController extends BaseController {
/**
* Instantiate a new UserController instance.
*/
public function __construct()
{
$this->beforeFilter('auth', array('except' => 'getLogin'));
$this->beforeFilter('csrf', array('on' => 'post'));
$this->afterFilter('log', array('only' =>
array('fooAction', 'barAction')));
}
}
Laravel框架中,你可以使用简单的REST命名规范,轻松定义单个路由去处理控制器的每个操作。首先,使用 Route::controller
方法定义路由:
定义一个 RESTful 控制器
Route::controller('users', 'UserController');
controller
方法接受两个参数。第一个是基础URI控制器句柄,第二个是控制器的类名。接下来,就可以在控制器中添加带有相应HTTP动词前缀的方法:
class UserController extends BaseController {
public function getIndex()
{
//
}
public function postProfile()
{
//
}
}
index
方法会应答带有这个控制器句柄的根URI(例如这个例子里的是 users
)。
如果你的控制器操作名称包含多个单词,你可以使用 "破折号" 语法来获得URI。例如,下面 UserController
控制器中的这个操作会用来应答 users/admin-profile
URI:
public function getAdminProfile() {}
资源控制器让围绕资源构建RESTful模式控制器变得更简单。比如,你可能希望创建一个的控制器,用来管理通过你的应用储存的图片( "photos" )。通过Artisan命令行输入 controller:make
命令以及路由中的 Route::resource
方法快速创建一个控制器。
如果要通过命令行创建控制器,使用如下命令:
php artisan controller:make PhotoController
现在我们可以为这个控制器注册一个资源模式的路由:
Route::resource('photo', 'PhotoController');
这一个路由声明创建了多个路由规则,用来处理各种图像(photo)资源的RESTful操作。同样地,刚刚创建的控制器中已经包含了许多对应的方法。每个方法都带有注释说明,告诉你分别是用来处理什么URI和HTTP动词的。
资源控制器中不同操作的用途
Verb | Path | Action | Route Name |
---|---|---|---|
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 |
有时你也许只需要处理其中一部分资源操作:
php artisan controller:make PhotoController --only=index,show
php artisan controller:make PhotoController --except=index
同样,你也许需要在路由中制定那一部分要处理的操作:
Route::resource('photo', 'PhotoController',
array('only' => array('index', 'show')));
Route::resource('photo', 'PhotoController',
array('except' => array('create', 'store', 'update', 'delete')));
当控制器中没有任何方法匹配请求时,就会调用一个全局响应的方法。这个方法命名为 missingMethod
,它接收请求的参数数组作为方法的唯一参数。
定义一个空方法
public function missingMethod($parameters)
{
//
}