HTTP 控制器
HTTP 控制器
简介
除了可以在单个的 routes.php
文件中定义所有的请求处理逻辑外,你可能还希望可以使用控制器类来组织此行为。控制器可将相关的 HTTP 请求处理逻辑组成一个类。控制器一般存放在 app/Http/Controllers
目录下。
基础控制器
这是一个基础控制器类的例子。所有 Lumen 控制器都应继承基础控制器类,它包含在 Lumen 的默认安装中:
<?php
namespace App\Http\Controllers;
use App\User;
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)]);
}
}
我们可以通过路由来指定控制器行为,就像这样:
$app->get('user/{id}', 'UserController@showProfile');
现在,当请求和此特定路由的 URI 相匹配时,UserController
类的 showProfile
方法就会被运行。当然,路由的参数也会被传递至该方法。
控制器和命名空间
有一点非常重要,那就是我们在定义控制器路由时,不需要指定完整的控制器命名空间。我们只需要定义「根」命名空间 App\Http\Controllers
之后的部分类名称即可。默认 `bootstrap/app.php
会将 routes.php
文件里的路由规则包在根控制器命名空间的路由群组下。
若你选择在 App\Http\Controllers
目录内层使用 PHP 命名空间嵌套或组织控制器,只要使用相对于 App\Http\Controllers
根命名空间的特定类名称即可。因此,若你的控制器类全名为 App\Http\Controllers\Photos\AdminController
,你可以像这样注册一个路由:
$app->get('foo', 'Photos\AdminController@method');
命名控制器路由
就像闭包路由,你可以指定控制器路由的名称:
$app->get('foo', ['uses' => 'FooController@method', 'as' => 'name']);
一旦你指定了控制器路由的名称,则可以很容易地生成能实现该行为的 URL。你也可以使用 action
辅助函数生成指向控制器行为的 URL。同样地,我们只需指定基类命名空间 App\Http\Controllers
之后的部分控制器类名称就可以了:
$url = action('FooController@method');
你也可以使用 route
辅助函数,生成命名控制器路由的 URL:
$url = route('name');
控制器中间件
可将 中间件 指定给控制器路由,例如:
$app->get('profile', [
'middleware' => 'auth',
'uses' => 'UserController@showProfile'
]);
不过,在控制器构造器中指定中间件会更为方便。在控制器构造器中使用 middleware
方法,你可以很容易地将中间件指定给控制器。你甚至可以对中间件作出限制,仅将它提供给控制器类中的某些方法。
class UserController extends Controller
{
/**
* 添加一个 UserController 实例。
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('log', ['only' => ['fooAction', 'barAction']]);
$this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
}
}
依赖注入与控制器
构造器注入
Lumen 服务容器 用于解析所有的 Lumen 控制器。因此,在此构造器中,你可以对控制器需要的任何依赖使用类型提示。依赖会自动被解析并注入控制器实例之中。
<?php
namespace App\Http\Controllers;
use App\Repositories\UserRepository;
class UserController extends Controller
{
/**
* 用户保存库实例。
*/
protected $users;
/**
* 创建新的控制器实例。
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
方法注入
除了构造器注入之外,你也可以对控制器行为方法的依赖使用类型提示。例如,让我们对 Illuminate\Http\Request
实例的其中一个方法使用类型提示:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
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
:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* 更新指定的用户。
*
* @param Request $request
* @param int $id
* @return Response
*/
public function update(Request $request, $id)
{
//
}
}