Laravel 11 请求对象与输入处理

在 Laravel 应用中,用户提交的数据通过 HTTP 请求进入系统。框架提供了强大的 Request 对象,用于以统一、安全的方式获取输入数据、文件、Cookie 等信息。 本章将系统讲解如何利用 Request 对象处理用户输入。

📥 注入 Request 对象

Request 对象可以通过依赖注入的方式在路由闭包或控制器方法中获取:

use Illuminate\Http\Request;

Route::post('/user', function (Request $request) {
    // 使用 $request 获取输入
    $name = $request->input('name');
    return "Hello, {$name}";
});

在控制器方法中同样可以注入:

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    public function store(Request $request)
    {
        $name = $request->input('name');
        // ...
    }
}

🔍 获取输入数据

Laravel 提供了多种方法从请求中获取数据,支持 GET、POST、JSON 等多种格式。

1. 获取所有输入
$input = $request->all();        // 返回数组,包含所有输入数据
$input = $request->input();      // 效果同上
2. 获取特定输入
$name = $request->input('name');               // 获取 name 字段的值,不存在返回 null
$name = $request->input('name', 'default');    // 指定默认值
$name = $request->name;                        // 使用动态属性(谨慎使用,推荐 input 方法)
3. 获取 JSON 输入

对于 Content-Type 为 application/json 的请求,可直接使用 input 方法获取 JSON 字段:

$data = $request->input('user.name');  // 支持点号访问嵌套数组
4. 获取部分输入
$only = $request->only(['name', 'email']);   // 只获取指定字段
$except = $request->except(['_token']);      // 排除指定字段
5. 判断输入是否存在
if ($request->has('name')) {
    // 字段存在且不为空
}
if ($request->filled('name')) {
    // 字段存在且不为空字符串
}
if ($request->missing('name')) {
    // 字段不存在或为空
}
6. 获取查询字符串参数

对于 GET 请求的查询参数,可以使用 query 方法:

$page = $request->query('page', 1);   // 获取 ?page= 的值,默认为 1

📎 处理上传文件

Laravel 简化了文件上传的处理流程,通过 file 方法可以获取上传的文件对象。

1. 获取上传文件
if ($request->hasFile('avatar')) {
    $file = $request->file('avatar');
    // 或使用动态属性:$request->avatar
}
2. 验证文件有效性
if ($request->file('avatar')->isValid()) {
    // 文件上传有效
}
3. 存储上传文件

使用 store 方法将文件保存到指定磁盘:

$path = $request->file('avatar')->store('avatars', 'public');
// 返回保存后的路径,如 'avatars/xxxx.jpg'

也可以指定文件名:

$path = $request->file('avatar')->storeAs('avatars', 'avatar.jpg', 'public');
💡 提示: 使用 store 方法前需要配置好文件系统(config/filesystems.php)。常用磁盘有 local(本地存储)、public(公共可访问)等。
4. 获取文件信息
$originalName = $request->file('avatar')->getClientOriginalName();
$extension    = $request->file('avatar')->getClientOriginalExtension();
$size         = $request->file('avatar')->getSize();   // 字节
$mimeType     = $request->file('avatar')->getMimeType();

📝 处理旧数据(Flash 数据)

在表单验证失败后重定向回表单页面时,经常需要保留用户已填写的输入值。Laravel 提供了 old 辅助函数和 Request 的 flash 方法。

1. 将输入数据闪存到 Session
$request->flash();                    // 将所有输入闪存到 Session
$request->flashOnly(['name', 'email']); // 只闪存指定字段
$request->flashExcept(['password']);   // 闪存除指定字段外的数据

通常在重定向之前调用:

return redirect()->back()->withInput();
2. 在 Blade 模板中获取旧数据
<input type="text" name="name" value="{{ old('name') }}">
💡 提示: old() 辅助函数会自动从 Session 中读取上一次闪存的输入数据,非常适用于表单回显。

🧩 高级技巧

1. 合并输入数据

可以在请求中动态添加或覆盖输入字段:

$request->merge(['key' => 'value']);
2. 替换输入数据

replace 方法会完全替换当前输入数组:

$request->replace(['name' => 'New Name']);
3. 获取请求路径和 URL
$path = $request->path();           // 请求路径,如 'user/1'
$url = $request->url();             // 不含查询字符串的 URL
$fullUrl = $request->fullUrl();     // 包含查询字符串的完整 URL
$method = $request->method();       // HTTP 方法,如 'POST'
if ($request->isMethod('post')) { } // 判断请求方法
4. 获取请求头
$userAgent = $request->header('User-Agent');
$token = $request->bearerToken();   // 获取 Bearer Token

🎯 实战示例:用户注册表单处理

以下是一个完整的控制器方法,展示如何处理注册表单的输入和文件上传:

public function register(Request $request)
{
    // 验证输入(简化示例)
    $validated = $request->validate([
        'name' => 'required|string|max:255',
        'email' => 'required|email|unique:users',
        'password' => 'required|min:8|confirmed',
        'avatar' => 'nullable|image|max:2048',
    ]);

    // 处理头像上传
    if ($request->hasFile('avatar')) {
        $path = $request->file('avatar')->store('avatars', 'public');
        $validated['avatar_path'] = $path;
    }

    // 创建用户
    $user = User::create($validated);

    // 登录用户
    auth()->login($user);

    // 重定向并闪存成功消息
    return redirect()->route('dashboard')->with('success', '注册成功!');
}
⚠️ 注意: 使用 validate 方法时,如果验证失败会自动抛出异常并重定向回上一页,携带错误信息和旧数据,无需手动处理。

❓ 常见问题

两者功能相同,getinput 的别名,都可以获取输入数据。推荐使用 input 以保持代码一致。

可以使用 $request->getContent() 获取原始请求体字符串,再通过 json_decode 解析。

常见原因包括:表单未设置 enctype="multipart/form-data",文件大小超出 php.ini 中的 upload_max_filesizepost_max_size,或者存储磁盘配置错误。

📝 小结

Request 对象是 Laravel 中处理用户输入的核心工具。通过依赖注入获取实例后,可以使用丰富的 API 获取各类输入数据,处理文件上传,管理旧数据等。 熟练掌握 Request 对象的使用,能让你的控制器代码更加简洁、安全。 下一章我们将深入学习表单验证,进一步提升应用的数据完整性。