未加星标

[ Laravel 5.4 文档 ] HTTP层 ―― 控制器

字体大小 | |
[开发(php) 所属分类 开发(php) | 发布者 店小二04 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏
1、简介

将所有的请求处理逻辑都放在单个路由文件中显然是不合理的,你也许还希望使用控制器类组织管理这些行为。控制器可以将相关的 HTTP 请求封装到一个类中进行处理。通常控制器存放在 app/Http/Controllers 目录中。

2、基本控制器 定义控制器

下面是一个基本控制器类的例子。所有的Laravel 控制器应该继承自 Laravel 自带的控制器基类 Controller ,控制器基类提供了一些很方便的方法如 middleware ,用于添加中间件到控制器动作:

<php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* 为指定用户显示详情
*
* @param int $id
* @return Response
*/
public function show($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}

我们可以像这样定义指向该控制器动作的路由:

Route::get('user/{id}', [email protected]');

现在,如果一个请求匹配上面的路由 URI, UserController 的 show 方法就会被执行。当然,路由参数也会被传递给这个方法。

注:控制器并不是一定要继承自基类,不过,那样的话就不能使用一些便利的方法了,比如 middleware 、 validate 和 dispatch 等。

控制器 & 命名空间

你应该注意到我们在定义控制器路由的时候没有指定完整的控制器命名空间,而只是定义了 App\Http\Controllers 之后的部分。默认情况下, RouteServiceProvider 将会在一个包含了命名空间的路由群组中载入路由文件,该路由群组指定了群组中路由控制器所在的命名空间,故而我们只需指定后面一部分类名即可。

如果你在 App\Http\Controllers 目录下选择使用 PHP 命名空间嵌套或组织控制器,只需要使用相对于 App\Http\Controllers 命名空间的指定类名即可。因此,如果你的完整控制器类是 App\Http\Controllers\Photos\AdminController ,则可以像这样注册路由:

Route::get('foo', 'Photos\[email protected]'); 单动作控制器

如果你想要定义一个只处理一个动作的控制器,可以在这个控制器中定义 __invoke 方法:

<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class ShowProfile extends Controller
{
/**
* Show the profile for the given user.
*
* @param int $id
* @return Response
*/
public function __invoke($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}

当你为这个单动作控制器注册路由的时候,不需要指定方法:

Route::get('user/{id}', 'ShowProfile'); 3、控制器中间件

中间件可以像这样分配给控制器路由:

Route::get('profile', [email protected]')->middleware('auth');

但是,将中间件放在控制器构造函数中更方便,在控制器的构造函数中使用 middleware 方法你可以很轻松的分配中间件给该控制器。你甚至可以限定该中间件应用到该控制器类的指定方法:

class UserController extends Controller
{
/**
* 实例化一个新的 UserController 实例
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('log')->only('index');
$this->middleware('subscribed')->except('store');
}
}

在控制器中还可以使用闭包注册中间件,这为我们定义只在某个控制器使用的中间件提供了方便,无需定义完整的中间件类:

$this->middleware(function ($request, $next) {
// ...
return $next($request);
});

注:你还可以将中间件分配给多个控制器动作,不过,这意味着你的控制器会变得越来越臃肿,这种情况下,需要考虑将控制器分割成多个更小的控制器。

4、资源控制器

Laravel 的资源控制器使得构建围绕资源的RESTful 控制器变得毫无痛苦,例如,你可能想要在应用中创建一个控制器,用于处理关于图片存储的 HTTP 请求,使用 Artisan 命令 make:controller ,我们可以快速创建这样的控制器:

php artisan make:controller PhotoController --resource

该 Artisan 命令将会生成一个控制器文件 app/Http/Controllers/PhotoController.php ,这个控制器包含了每一个资源操作对应的方法。

接下来,可以为该控制器注册一个资源路由:

Route::resource('photos', 'PhotoController');

这个路由声明包含了处理图片资源 RESTful 动作的多个路由,相应地,Artisan 生成的控制器也已经为这些动作设置了对应的处理方法。

资源控制器处理的动作 方法 路径 动作 路由名称 GET /photos index photos.index GET /photos/create create photos.create POST /photos store photos.store GET /photos/{photo} show photos.show GET /photos/{photo}/edit edit photos.edit PUT/PATCH /photos/{photo} update photos.update DELETE /photos/{photo} destroy photos.destroy 指定资源模型

如果你在使用路由模型绑定并且想要在资源控制器的方法中对模型实例进行类型提示,可以在生成控制器的使用使用 --model 选项:

php artisan make:controller PhotoController --resource --model=Photo 伪造表单方法

由于 HTML 表单不能发起 PUT 、 PATCH 和 DELETE 请求,需要添加一个隐藏的 _method 字段来伪造 HTTP 请求方式,辅助函数 method_field 可以帮我们做这件事:

{{ method_field('PUT') }} 部分资源路由

声明资源路由时可以指定该路由处理的动作子集:

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']
]); 命名资源路由参数

默认情况下, Route::resource 将会基于资源名称的单数格式为资源路由创建路由参数,你可以通过在选项数组中传递 parameters 来覆盖这一默认设置。 parameters 应该是资源名称和参数名称的关联数组:

Route::resource('user', 'AdminUserController', ['parameters' => [
'user' => 'admin_user'
]]);

上面的示例代码会为资源的 show 路由生成如下 URL:

/user/{admin_user} 补充资源控制器

如果有必要在默认资源路由之外添加额外的路由到资源控制器,应该在调用 Route::resource 之前定义这些路由;否则,通过 resource 方法定义的路由可能无意中优先于补充的额外路由:

Route::get('photos/popular', [email protected]');
Route::resource('photos', 'PhotoController');

注:注意保持控制器的单一职责,如果你发现指向控制器动作的路由超过默认提供的资源控制器动作集合了,考虑将你的控制器分割成多个更小的控制器。

5、依赖注入 & 控制器 构造函数注入

Laravel 使用服务容器解析所有的 Laravel 控制器,因此,可以在控制器的构造函数中类型声明任何依赖,这些依赖会被自动解析并注入到控制器实例中:

<?php
namespace App\Http\Controllers;
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契约,如果容器可以解析,就可以进行类型提示。注入依赖到控制器可以让应用更加易于测试。

方法注入

除了构造函数注入之外,还可以在控制器的动作方法中进行依赖的类型提示,例如,我们可以在某个方法中类型提示 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}', [email protected]');

你需要通过定义控制器方法如下所示来类型提示 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
* @translator http://laravelacademy.org
*/
public function update(Request $request, $id)
{
//
}
} 6、路由缓存

注:路由缓存不会作用于基于闭包的路由。要使用路由缓存,必须将闭包路由转化为控制器路由。

如果你的应用完全基于控制器路由,可以使用 Laravel 的路由缓存,使用路由缓存将会极大减少注册所有应用路由所花费的时间开销,在某些案例中,路由注册速度甚至能提高100倍!想要生成路由缓存,只需执行 Artisan 命令 route:cache :

php artisan route:cache

运行完成后,每次请求都会从缓存中读取路由,记住,如果你添加新的路由需要重新生成路由缓存。因此,只有在项目部署阶段才需要运行 route:cache 命令。

想要移除缓存路由文件,使用 route:clear 命令即可:

php artisan route:clear

本文开发(php)相关术语:php代码审计工具 php开发工程师 移动开发者大会 移动互联网开发 web开发工程师 软件开发流程 软件开发工程师

主题: Laravel中间件RESTPHPHTMLUT
分页:12
转载请注明
本文标题:[ Laravel 5.4 文档 ] HTTP层 ―― 控制器
本站链接:http://www.codesec.net/view/532206.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 开发(php) | 评论(0) | 阅读(64)