如何在Laravel中通过依赖注入获取HTTP请求实例及路由参数详解

<?php
App 的 Http 控制器所在的命名空间。;
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 string $id
* @return Response
*/
public function update(Request $request, $id)
{
//
}
}
通过闭包路由获取参数
你可以在路由闭包里使用 Illuminate\Http\Request 类,并且服务容器会自动把请求参数注入到路由闭包中。
use Illuminate\Http\Request;
Route::get('/', function (Request $request) {
//
});
请求路径 & 方法
Illuminate\Http\Request 实例具备一系列可用于验证 HTTP 请求参数的方法,并且它继承了 Symfony\Component\HttpFoundation\Request 类。以下是该类的一些重要方法:
获取请求路径
路径方法会返回请求的路径信息。因此,倘若请求的路径为 ,那么路径方法将会返回 foo/bar。
$uri = $request->path();
可以验证传入的请求路径是否与给定的模式相匹配。在这个方法里,你能够使用 * 字符当作通配符。
if ($request->is('admin/*')) {
//
}
获取请求 URL
能够通过 url 方法或者 fullUrl 方法来获取完整的请求 URL。其中,url 方法会返回不包含查询串的 URL,而 fullUrl 方法则能获取包含查询串的 URL。
// 不附带查询串...
$url = $request->url();
// 附带查询串...
$url = $request->fullUrl();
获取请求 Method
方法会返回请求的 HTTP 动作。并且能够利用 isMethod 方法来检验 HTTP 动作是否与给定的相匹配。
$method = $request->method();
if ($request->isMethod('post')) {
//
}
PSR-7 请求
PSR-7 标准对 HTTP 消息接口进行了定义,其中包含了请求和响应。若你想要使用 PSR-7 请求来替代 Laravel 请求,那么就需要先安装若干个库。Laravel 利用 Symfony HTTP Message Bridge 组件,把通常的 Laravel 请求以及响应转变为 PSR-7 兼容的实现。
composer require symfony/psr-http-message-bridge
需要安装 zendframework,可通过 composer 来进行操作。/zend-diactoros
安装了这些库之后,就能够通过在路由闭包里或者控制器方法中的请求接口类型提示来获取 PSR - 7 请求。
使用 Psr\Http\Message\ServerRequestInterface 这个接口。;
Route::get('/', function (ServerRequestInterface 是一个接口,它表示一个服务器请求。这个接口通常用于处理 HTTP 请求等服务器相关的操作。它提供了一些方法来获取请求的相关信息,如请求方法、请求头、请求体等。通过这个接口,开发者可以方便地对服务器请求进行处理和操作。) {
//
});
如果从路由或控制器中返回了 PSR-7 响应实例,那么框架就会自动把它转换回 Laravel 响应实例并且进行显示。
输入的裁剪和标准化
Laravel 在应用的全局中间件堆栈中默认包含了 TrimStrings 中间件和 ConvertEmptyStringsToNull 中间件。这些中间件处于 App\Http\Kernel 类的堆栈列表里。它们会自动裁剪请求里的所有输入字符串域,并且把空字符串域转化为 null。这样一来,你就不必担心路由和控制器中的标准化规约问题。
要禁用这个行为,只需从 App\Http\Kernel 类的 $middleware 属性中移除它,这就相当于从应用的中间件堆栈中移除它。
获取输入获取所有的输入数据
可以使用 all 方法获取所有输入数据数组:
$input = $request->all();
获取单个输入值
使用一些简便的方式,就能够借助 Illuminate\Http\Request 这个实例来获取用户的所有输入。并且无需担忧用户请求所采用的是何种 HTTP 动作。不管是哪种 HTTP 动作,用户的请求都可以通过 input 方法进行获取。
$name = $request->input('name');
可以把默认值当作传递给 input 方法的第二个参数。此值会在请求未包含该参数时被返回。
$name = $request->input('name', 'Sally');
在与包含数组输入的表单进行协作的时候,要通过使用“点”运算符来访问数组元素。
$name = $request->input('products.0.name');
$names = $request->input('products.*.name');
调用 input 方法时不带参数,就可以获取到全部的输入值,这些输入值是以关联数组的形式存在的。
$input = $request->input();
从查询串中获取输入
语言风格:保持原文风格,去掉最前面的序号,把长句拆分成多个小
$name = $request->query('name');
如果查询串值不存在,那么 query 方法的第二个参数会被当作该参数的默认值而被返回。
$name = $request->query('name', 'Helen');
调用 query 方法时不带参数,就能够获取到以关联数组形式呈现的查询串的所有值。
$query = $request->query();
通过动态属性获取输入
能够利用 Illuminate\Http\Request 实例的动态属性来获取用户输入。举例来说,倘若应用表单里包含 name 域,那就可以按照如下方式去访问该域的值。
$name = $request->name;
使用动态属性时,Laravel 首先会在请求载体里查找参数的值。若该值不存在,Laravel 会在路由参数中进行搜索。
获取 JSON 输入
向应用传递 JSON 请求时,能够通过 input 方法来访问 JSON 数据,条件是把请求的 Content-Type 头设定为 application/json。也可以运用“点”语法去访问 JSON 数组。
$name = $request->input('user.name');
获取部分输入数据
如果要获取输入数据的子集,那么可以运用 only 方法或者 except 方法。这两种方法能够接受单个 array ,也可以接受动态参数列表。
$input = $request->only(['username', 'password']);
$input = $request->only('username', 'password');
$input = $request->except(['credit_card']);
$input = $request->except('credit_card');
Tip:方法仅返回请求中的所有键值对;然而它不会返回请求中不存在的键值对。
判断输入值是否存在
has 方法的作用是判定请求中是否存在指定的值。若请求中存在该值,那么 has 方法就会返回 true 。
if ($request->has('name')) {
//
}
如果给出一个数组,那么 has 方法会去判断在请求当中,指定的值是否全部都存在。
if ($request->has(['name', 'email'])) {
//
}
要判断一个值在请求中是否存在且不为空,就需要运用 filled 方法。
if ($request->filled('name')) {
//
}
旧数据
Laravel 能够让你在两次请求之间留存数据。此特性在有效性校验出现错误后用于重新填充表单时是很有帮助的。然而,倘若你使用 Laravel 自带的验证特性,就无需自己手动去调用这些方法,因为一些 Laravel 内置的验证功能会自动进行调用。
将输入数据传送到 Session
Illuminate\Http\Request 类的 flash 方法会把当前的输入传递到 session 中,并且在用户向应用发出这一次请求时这些输入仍然是可用的。
$request->flash();
你可以运用 flashOnly 或者 flashExcept 这种方法,把请求数据的一部分传递给 session。这些方法通常被用来把像密码这类敏感数据从 session 保持中排除出去。
$request->flashOnly(['username', 'email']);
$request->flashExcept('password');
传送数据并跳转
当你时常需要把输入传送给 session 并且紧接着跳转到之前的页面时,能够通过在跳转函数之后连接调用 withInput 方法来轻松实现这一操作。
return redirect('form')->withInput();
return redirect('form')->withInput(
$request->except('password')
);
获取旧数据
要获取之前请求传送的数据,能够使用 Request 实例的 old 方法。该 old 方法会从 session 中提取之前传送的那个值。
$username = $request->old('username');
Laravel 提供了全局的 old 助手。在 Blade 模板中显示旧数据时,old 助手较为易用。若给定域的旧值不存在,它就会返回 null 。
<input type="text" name="username" value="{{ old('username') }}">
Cookies从请求中获取 Cookies
Lavarel 框架生成的所有 cookies 均为加密状态,并且已通过授权码进行签名。这表明一旦这些 cookies 被客户端进行更改,它们就会失去效力。通过使用 Illuminate\Http\Request 实例的 cookie 方法,能够从请求当中获取到 cookie 的值。
$value = $request->cookie('name');
能够通过 Cookie facade 来获取 cookie 的值:
$value = Cookie::get('name');
将 Cookies 附加到响应中
可以使用 cookie 方法将 cookie 附加到输出的 Illuminate\Http\Response 实例上。需要向该方法传递名称、值以及 cookie 的过期时间(以分钟为单位)。
return response('Hello World')->cookie(
'name', 'value', $minutes
);
cookie 能够接受另外一些不太常用的参数。通常这些参数与 PHP 内置的 setcookie 方法的参数具有相同的作用和意义。
return response('Hello World')->cookie(
'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
);
同样,你能够运用 Cookie facade 去“排列”那些要从应用中附加到输出响应里的 cookies。queue 这个方法会接收一个 Cookie 实例或者创建 Cookie 所需要的参数列表。这些 cookies 会在输出响应被发送到浏览器之前被附加上去。
Cookie::queue(Cookie::make('name', 'value', $minutes));
Cookie::queue('name', 'value', $minutes);
生成 Cookie 实例
如果要生成一个能够随后提供给响应实例的 Symfony\Component\HttpFoundation\Cookie 实例,那么可以运用全局的 cookie 助手。此 cookie 在未附加到响应实例之前,是不会传回给客户端的。
$cookie = cookie('name', 'value', $minutes);
return response('Hello World')->cookie($cookie);
文件获取上传的文件
可以利用 Illuminate\Http\Request 实例的 file 方法,也可以通过动态属性访问来获取上传文件。其中,file 方法会返回 Illuminate\Http\UploadedFile 类的实例,该类是对 PHP 的 SplFileInfo 类进行扩展的,并且提供了多个用于文件交互的方法。
$file = $request->file('photo');
$file = $request->photo;
可以使用 hasFile 方法判断请求中是否存在指定文件:
if ($request->hasFile('photo')) {
//
}
验证成功上传
可以使用 isValid 方法来校验上传的文件是否有问题,同时也可以验证文件是否存在。
if ($request->file('photo')->isValid()) {
//
}
文件路径 & 扩展名
UploadedFile 类包含着能够访问文件的全路径以及扩展名的方法。extension 方法会依据文件的内容去推测与之匹配的文件扩展名。并且,这个推测出的扩展名有可能和客户端所提供的扩展名不一样。
$path = $request->photo->path();
$extension = $request->photo->extension();
其它的文件方法
UploadedFile 实例存在着其他几个可供使用的方法。通过浏览这个类的 API 文档,能够获取关于这些方法的更多信息。
存储上传文件
要存储上传的文件,首先需要配置好文件系统。你能够利用 UploadedFile 的 store 方法,将上传的文件转移到你的某个磁盘上,这个文件或许处于本地文件系统的某个位置,亦或是像 Amazon S3 这样的云存储位置。
store 方法会接受一个路径,这个路径是相对于文件系统配置的存储文件根目录的。该路径不能包含文件名,因为系统会自动生成唯一的 ID 来作为文件名。
store 方法会接受一个可选的第二个参数,此参数可用于存储文件的磁盘名称。该方法会返回一个相对于磁盘根目录的文件路径。
$path = $request->photo->store('images');
$path = $request->photo->store('images', 's3');
如果你不希望自动生成文件名,那么能够使用 storeAs 方法。此方法接受路径、文件名以及磁盘名作为它的参数。
$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');
配置可信代理
如果你的应用程序在运行时处于失效的 TLS/SSL 证书的负载均衡器之后,那么你或许会察觉到你的应用程序有时无法生成 HTTPS 链接。通常这种情况是因为你的应用程序正在把从端口 80 上的负载均衡器传来的流量进行转发,然而它并不知道是否应当生成安全链接。
在 Laravel 应用程序中包含 App\Http\Middleware\TrustProxies 中间件,这样就能解决这个问题,它能让你快速对应用程序信任的负载均衡器或代理进行自定义。你的可信代理应当以数组的形式列在这个中间件的 $proxies 属性中。除了要进行配置受信任的代理这一操作外,还能够进行配置那些应该被信任的代理这一操作。
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
使用 Fideloper\Proxy\TrustProxies 。as Middleware;
class TrustProxies extends Middleware
{
/**
* 应用程序的可信代理列表
*
* @var array
*/
protected $proxies = [
'192.168.1.1',
'192.168.1.2',
];
/**
* 应该用来检测代理的头信息
*
* @var string
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}
如果你在使用 AWS 弹性负载平衡,那么你的 $header 值应当是 Request::HEADER_X_FORWARDED_AWS_ELB。对于常量的更多相关信息,若要用于 $headers 属性,可查看 Symfony 的文档以信任代理。
信任所有代理
若你在使用 Amazon AWS 或者其他的“云”负载均衡器提供程序,或许并不知晓负载均衡器的实际 IP 地址。在这样的情形下,你能够使用*来对所有代理予以信任。
/**
* 应用程序的可信代理列表
*
* @var array
*/
protected $proxies = '*';
本文章首发在 网站上。