什么是 Request 对象
Illuminate\Http\Request 是一个用面向对象方式处理应用所接收 HTTP 请求的类。
你可以通过它访问请求中包含的所有信息,包括表单数据、查询字符串、上传文件、请求头等。
向控制器注入请求
在控制器方法中,只要为 Illuminate\Http\Request 添加类型提示,Laravel 的服务容器就会自动注入请求实例。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function store(Request $request): RedirectResponse
{
$name = $request->input('name');
// 保存用户的处理...
return redirect('/users');
}
}
在路由闭包中也可以以相同方式添加类型提示。
use Illuminate\Http\Request;
Route::get('/', function (Request $request) {
// ...
});
与路由参数一起使用
如果控制器方法同时接收路由参数,请把路由参数写在 Request 之后。
use App\Http\Controllers\UserController;
Route::put('/user/{id}', [UserController::class, 'update']);
public function update(Request $request, string $id): RedirectResponse
{
// 通过 $request 访问请求数据,通过 $id 访问路由参数
return redirect('/users');
}
获取请求数据
获取所有输入数据
all 方法将所有输入数据以数组形式返回。
无论是 HTML 表单请求还是 XHR 请求都可以使用。
$input = $request->all();
获取指定字段
input 方法与 HTTP 方法无关,会从整个请求负载(包括查询字符串)中读取值。
$name = $request->input('name');
在第二个参数中可以指定值不存在时的默认值。
$name = $request->input('name', 'Sally');
数组类型的输入可以使用点号记法访问。
$name = $request->input('products.0.name');
$names = $request->input('products.*.name');
获取查询字符串
query 方法只从查询字符串(URL 中 ? 之后的部分)中获取值。
$name = $request->query('name');
$name = $request->query('name', 'Helen');
// 以数组形式获取所有查询字符串
$query = $request->query();
input 同时覆盖请求体和查询字符串,而 query 只覆盖查询字符串。
如果要区分表单 POST 数据和 URL 参数,可以使用 query。
类型化获取
除了 input 外,Laravel 还提供了按指定类型获取值的方法。
// 作为字符串获取(Stringable 实例)
$name = $request->string('name')->trim();
// 作为整数获取
$perPage = $request->integer('per_page');
// 作为布尔值获取("1"、"true"、"on"、"yes" → true)
$archived = $request->boolean('archived');
// 作为数组获取
$versions = $request->array('versions');
// 作为 Carbon 实例获取日期
$birthday = $request->date('birthday');
动态属性
也可以直接以字段名作为属性来访问。
使用动态属性时,会先在请求负载中查找值,若找不到再在路由参数中查找。
获取部分输入数据
可以通过 only 和 except 获取输入数据的子集。
$input = $request->only(['username', 'password']);
$input = $request->except(['credit_card']);
判断输入是否存在
使用 has 方法判断请求中是否包含某个值。
if ($request->has('name')) {
// ...
}
// 判断是否同时包含多个键
if ($request->has(['name', 'email'])) {
// ...
}
如果要排除空字符串,判断是否有值,请使用 filled。
if ($request->filled('name')) {
// ...
}
若值不存在或为空字符串,可以使用 isNotFilled。
if ($request->isNotFilled('name')) {
// ...
}
请求路径与方法的判定
获取和判定路径
// 获取路径(例:"foo/bar")
$uri = $request->path();
// 判断是否匹配某种模式(支持通配符 *)
if ($request->is('admin/*')) {
// ...
}
// 判断是否匹配某个命名路由
if ($request->routeIs('admin.*')) {
// ...
}
获取 URL
// 不带查询字符串的 URL
$url = $request->url();
// 带查询字符串的 URL
$urlWithQueryString = $request->fullUrl();
判断 HTTP 方法
使用 isMethod 判断 HTTP 方法。
$method = $request->method();
if ($request->isMethod('post')) {
// 只处理 POST 请求
}
文件上传
获取已上传的文件
使用 file 方法获取上传的文件。
它会返回一个 Illuminate\Http\UploadedFile 实例。
$file = $request->file('photo');
// 也可以通过动态属性获取
$file = $request->photo;
要判断文件是否存在,请使用 hasFile。
if ($request->hasFile('photo')) {
// ...
}
保存文件
使用 store 方法将文件保存到存储中。
文件名会自动生成。
// 保存到默认磁盘的 "images" 目录
$path = $request->photo->store('images');
// 保存到 S3
$path = $request->photo->store('images', 's3');
如果需要指定文件名,请使用 storeAs。
$path = $request->photo->storeAs('images', 'filename.jpg');
接受文件上传时,务必校验文件的种类和大小。
建议使用校验来安全地处理。
示例:接收表单数据
以下示例展示了在控制器中接收用户注册表单数据。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class RegisterController extends Controller
{
public function store(Request $request): RedirectResponse
{
// 获取表单数据
$name = $request->input('name');
$email = $request->input('email');
$password = $request->input('password');
// 只取需要的数据
$data = $request->only(['name', 'email', 'password']);
// 创建用户的处理...
return redirect('/dashboard');
}
}
定义对应的路由。
use App\Http\Controllers\RegisterController;
Route::post('/register', [RegisterController::class, 'store']);
下一步