访问请求
要通过依赖注入获取当前 HTTP 请求的实例,你需要在类的控制器方法中使用 Illuminate\Http\Request
类型提示。进入的请求实例将会通过服务容器自动注入:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller { /** * Store a new user. * * @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 { /** * Update the specified user. * * @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
类。下面我们来讨论一些非常重要的方法。
获取请求路径
path
方法返回请求的路径信息。因此,如果进入的请求目标是 http://domain.com/foo/bar
,那么 path
方法将返回 foo/bar
:
$uri = $request->path();
is
方法可以校验进入的请求路径是否与指定的规则相符。当使用这个方法时,你还可以使用 *
字符作为通配符:
if ($request->is('admin/*')) { // }
获取请求的 URL
要从进入的请求获取完整的 URL,你可以使用 url
或 fullUrl
方法。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 消息桥接组件来把典型的 Laravel 请求转换为与 PSR-7 标准一致的实现:
composer require symfony/psr-http-message-bridge composer require zendframework/zend-diactoros
当你安装好这些库后,你可以在路由闭包或控制器中使用请求接口的类型提示来获取 PSR-7 请求:
use Psr\Http\Message\ServerRequestInterface; Route::get('/', function (ServerRequestInterface $request) { // });
如果你从路由或控制器返回了一个 PSR-7 响应实例,它会被框架自动转换会 Laravel 响应实例并展示。
获取输入
获取所有输入数据
你可以使用 all
方法获取所有输入信息作为一个 array
:
$input = $request->all();
获取单个输入值
通过一些简单的方法,你可以获取到 Illuminate\Http\Request
实例中用户输入的所有数据,而不必的考虑请求使用的哪个 HTTP 动词,input
方法可以用来获取用户输入:
$name = $request->input('name');
你可以把默认值作为第二个参数传递给 input
方法。如果请求中的值没有设置的话,将会返回该默认值:
$name = $request->input('name', 'Sally');
当表单中包含数组输入时,可以使用“点号”来访问数组:
$name = $request->input('products.0.name'); $names = $request->input('products.*.name');
使用动态属性获取输入值
你还可以使用 Illuminate\Http\Request
实例的动态属性来获取用户输入。例如,你应用的表单包含一个 name
字段,你可以这样获取该字段的值:
$name = $request->name;
当使用动态属性时,Laravel 会首先查找请求中参数的值,如果没有设置,Laravel 将会从路由参数中查找该值。
获取 JSON 输入值
当向你的应用发送 JSON 请求时,若请求头中 Content-Type
的值为 application/json
,你就可以使用 input
获取该 JSON 数据。你甚至可以使用“点”语法来获取 JOSN 数组中的值:
$name = $request->input('user.name');
获取输入数据的一部分
如果你只想获取输入数据的一部分,那么你可以使用 only
和 except
方法。这两个方法都接收一个数组或参数的动态列表:
$input = $request->only(['username', 'password']); $input = $request->only('username', 'password'); $input = $request->except(['credit_card']); $input = $request->except('credit_card');
判断输入值是否存在
你可以使用 has
方法来判断输入中某个值是否存在。如果该值存在则 has
方法会返回 true
,否则会返回一个空字符串:
if ($request->has('name')) { // }
旧输入数据
Laravel 允许你在下次请求前保存本次请求数据。这个特性对于验证失败后重新填写表单非常有用。然而,如果你使用 Laravel 自带的验证服务,那就不需要你手动使用该方法,因为 Laravel 的一些内置验证功能会自动调用它们。
闪存输入到 Session
Illuminate\Http\Request
类的 flush
方法会闪存当前输入数据到 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
从请求中获取 cookie
Laravel 框架创建的所有 cookie 都是经过加密的,并通过一个授权码进行签名,如果它们被客户端修改过,那它们将会被认为是无效的。要从请求中获取 cookie 的值,使用 Illuminate\Http\Request
实例中的 cooike
方法:
$value = $request->cookie('name');
向响应中附加 cookies
你还可以在 Illuminate\Http\Response
实例上使用 cookie
方法来给其附加 cookie。你需要给该方法传递一个名称、值、以及该 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 实例
如果你想生成一个 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
方法接收一个路径,这个路径是文件将被存储的,你配置好的根目录的相对路径。这个路径不应该包含文件名,因为文件名会根据文件内容是由 MD5 哈希值自动生成。
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');
该篇属于专题:《Laravel 5.3 中文文档》