跳转到主要内容

什么是校验

校验(Validation)指的是验证用户提交的数据是否符合预期的格式与条件。 Laravel 通过请求对象的 validate 方法,以及专用的 Form Request 类,提供了简洁而强大的校验能力。

在控制器中做校验

$request->validate() 的用法

在控制器方法中调用 $request->validate() 是最直接的校验方式。 校验失败时,Laravel 会自动把用户重定向回前一页,并把错误信息存入 Session。 定义路由:
use App\Http\Controllers\PostController;

Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);
编写控制器:
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class PostController extends Controller
{
    public function create(): View
    {
        return view('post.create');
    }

    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'body'  => 'required|string',
            'email' => 'required|email',
        ]);

        // 使用校验后的数据保存文章...

        return redirect('/posts');
    }
}
validate 接收以字段名为键、规则为值的数组。 规则可以用 | 分隔或使用数组。
// 用竖线分隔
'title' => 'required|string|max:255',

// 数组
'title' => ['required', 'string', 'max:255'],

主要校验规则

规则说明
required值必须存在且非空
string必须是字符串
email必须是合法邮箱格式
min:值字符串长度或数值不少于指定值
max:值字符串长度或数值不超过指定值
unique:表在指定表中值唯一
nullable允许 null
integer必须是整数
boolean布尔值(true/false1/0 等)
date有效的日期格式
confirmed字段名_confirmation 字段一致
完整规则请见官方文档

使用校验后的数据

validate 的返回值是只包含通过校验字段的数组,可作为可信数据使用。
$validated = $request->validate([
    'title' => 'required|string|max:255',
    'body'  => 'required|string',
]);

Post::create($validated);

Blade 中展示错误

校验失败时,Laravel 会让所有视图都能自动访问 $errors 变量。 这由 web 中间件组中的 ShareErrorsFromSession 中间件负责。

列出全部错误

@if ($errors->any())
    <ul>
        @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
@endif

按字段展示错误

使用 @error 指令可在字段旁行内显示错误:
<label for="title">标题</label>

<input
    id="title"
    type="text"
    name="title"
    value="{{ old('title') }}"
    class="@error('title') is-invalid @enderror"
/>

@error('title')
    <div class="error-message">{{ $message }}</div>
@enderror
使用 old('字段名') 可在校验失败后仍将用户输入的值填回表单。

Form Request

什么是 Form Request

当校验逻辑较复杂时,可将其抽离到「Form Request」类中。 Form Request 将校验与授权逻辑集中到一个自定义请求类中。

创建 Form Request

make:request Artisan 命令生成:
php artisan make:request StorePostRequest
会生成 app/Http/Requests/StorePostRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    /**
     * 判断是否有权限执行此请求
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * 返回应用到此请求的校验规则
     */
    public function rules(): array
    {
        return [
            'title' => 'required|string|max:255',
            'body'  => 'required|string',
            'email' => 'required|email|unique:posts',
        ];
    }
}

rules() 方法

以数组形式返回校验规则,与直接传给 validate 的一致。

authorize() 方法

判断是否有权限执行该请求。 返回 true 通过,返回 false 时自动返回 403。 若只允许已认证用户,可用 auth()->check()。 教程中直接返回 true 即可。
authorize 返回 false 时,控制器方法不会执行,会直接返回 403 Forbidden。

注入到控制器

只需在控制器方法上做类型提示即可使用 Form Request。 控制器执行前会先运行校验,因此无需在方法内再写校验代码。
use App\Http\Requests\StorePostRequest;

class PostController extends Controller
{
    public function store(StorePostRequest $request): RedirectResponse
    {
        // 到达此处即校验通过

        $validated = $request->validated();

        Post::create($validated);

        return redirect('/posts');
    }
}
$request->validated() 只返回校验过的数据。

实践示例:创建并保存投稿表单

以下是从展示表单到提交、校验、保存的完整流程:
1

定义路由

use App\Http\Controllers\PostController;

Route::get('/posts/create', [PostController::class, 'create']);
Route::post('/posts', [PostController::class, 'store']);
2

生成 Form Request

php artisan make:request StorePostRequest
public function rules(): array
{
    return [
        'title' => 'required|string|max:255',
        'body'  => 'required|string',
    ];
}

public function authorize(): bool
{
    return true;
}
3

实现控制器

use App\Http\Requests\StorePostRequest;
use App\Models\Post;

class PostController extends Controller
{
    public function create(): View
    {
        return view('posts.create');
    }

    public function store(StorePostRequest $request): RedirectResponse
    {
        Post::create($request->validated());

        return redirect('/posts');
    }
}
4

创建 Blade 模板

{{-- resources/views/posts/create.blade.php --}}

<h1>新建文章</h1>

@if ($errors->any())
    <ul>
        @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
@endif

<form method="POST" action="/posts">
    @csrf

    <div>
        <label for="title">标题</label>
        <input
            id="title"
            type="text"
            name="title"
            value="{{ old('title') }}"
        />
        @error('title')
            <span>{{ $message }}</span>
        @enderror
    </div>

    <div>
        <label for="body">正文</label>
        <textarea id="body" name="body">{{ old('body') }}</textarea>
        @error('body')
            <span>{{ $message }}</span>
        @enderror
    </div>

    <button type="submit">发表</button>
</form>
Blade 表单请务必包含 @csrf 指令,否则 Laravel 会返回 419 错误。

下一步

HTTP 请求

回顾使用请求对象获取数据的方式。
最后修改于 2026年7月13日