表单验证

Laravel 提供了几种不同的方法来验证传入应用程序的数据。最常见的做法是在所有传入的 HTTP 请求中使用 validate方法。

快速验证

定义路由

首先,在 routes/web.php 路由文件中定义了下面这些路由

use App\Http\Controllers\PostController;

// 页面路由
Route::get('/post/index', [PostController::class, 'index']);

// 处理提交数据的路由
Route::post('/post/add', [PostController::class, 'add']);

创建控制器

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class PostController extends Controller
{
    /**
     * 显示创建博客文章的表单。
     *
     * @return \Illuminate\View\View
     */
    public function index()
    {
        return view('post.create');
    }

    /**
     * 存储一篇新的博客文章。
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function add(Request $request)
    {
        // 验证并存储博客文章...
    }
}

编写验证逻辑

将使用 Illuminate\Http\Request 类提供的 validate 方法。如果验证通过,你的代码会继续正常运行。如果验证失败,则会抛出异常,并自动将对应的错误响应返回给用户。验证规则可以以|分割字符串写法或者以数组写法,如下:

use Illuminate\Http\Request;

public function store(Request $request)
{
    $validated = $request->validate([

        // 字符串写法
        'title' => 'required|unique:posts|max:255',
        // 数组写法
        'title' => ['required', 'unique:posts', 'max:255'],
        'body' => 'required',
    ]);

    // 博客文章验证通过...
}

希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中

$request->validate([
    'title' => 'bail|required|unique:posts|max:255',
    'body' => 'required',
]);

请求包含「嵌套」参数, 你可以在验证规则中使用「点」语法来指定这些参数

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'author.name' => 'required',
    'author.description' => 'required',
]);

显示验证错误信息

如果传入的请求参数未通过给定的验证规则呢?正如前面所提到的,Laravel 会自动将用户重定向到之前的位置。另外,所有的验证错误信息和 请求输入 都将自动存储到 闪存 session

<!-- /resources/views/post/index.blade.php -->

<h1>Create Post</h1>

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<!-- Create Post Form -->
@error 指令

也可以使用 @error Blade 指令方便地检查给定的属性是否存在验证错误信息。在 @error 指令中,你可以输出 $message 变量以显示错误信息

<!-- /resources/views/post/index.blade.php -->

<label for="title">Post Title</label>

<input id="title" type="text" class="@error('title') is-invalid @enderror">

@error('title')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror

自定义错误消息

第一种自定义错误信息

Laravel 的内置验证规则每个都有一条错误消息,位于应用程序的 resources/lang/en/validation.php 文件中。在此文件中,你将找到每个验证规则的翻译条目。你可以根据应用程序的需求随意更改或修改这些消息。

此外,你可以将此文件复制到另一个翻译语言的目录中,以翻译应用程序语言的消息。要了解有关 Laravel 本地化的更多信息,请查看完整的 本地化文档

第二种自定义错误信息
 <?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

// 引入Validator 门面 
use Illuminate\Support\Facades\Validator;

class PostController extends Controller
{
    /**
     * 显示创建博客文章的表单。
     *
     * @return \Illuminate\View\View
     */
    public function index()
    {
        return view('post.create');
    }

    /**
     * 存储一篇新的博客文章。
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function add(Request $request)
    {
        // 验证规则
        $rules = [
            'title' => 'required|unique:posts|max:255',
            'author.name' => 'required',
            'author.description' => 'required',
        ];

        // 错误提示信息
        $message = [
            'title.required' => '标题必填',
            'title.unique' => '该标题已存在,请更换标题',
            'title.max' => '标题可输入255个字符',
            'author.name' => '作者名字必填',
            'author.description' => '作者简介必填'
        ];

        // make 方法将会生成一个新的验证器实例
        $validator = Validator::make($request->all(), $rules,$message);

        if($validator->fails())
        {
            // withErrors 方法将错误信息存储至 session 中。使用该方法时,$errors 会自动与之后的视图共享,将其回显给用户
            return redirect('/post/index')->withErrors($validator)->withInput();
        }
    }
}

make方法中的第一个参数是期望校验的数据。第二个参数是应用到数据上的校验规则。

重新填写表单

当 Laravel 由于验证错误而生成重定向响应时,框架将自动 将所有请求的输入闪存到 session 中。 这样做是为了方便你在下一个请求期间访问输入,并重新填充用户尝试提交的表单。

要从先前的请求中检索闪存的输入,请在 Illuminate\Http\Request 的实例上调用 old 方法。 old 方法将从 session 中提取先前闪存的输入数据

$title = $request->old('title');

Laravel 还提供了一个全局性的 old。如果要在 Blade 模板 中显示旧输入,则使用 old 来重新填充表单会更加方便。如果给定字段不存在旧输入,则将返回 null

<input type="text" name="title" value="{{ old('title') }}">

如果某个字段属于可选字段,但是 null 会被验证器标识为非法,如果不想被验证器标识为非法的话,那么需要将 nullable 添加到可选字段规则

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
    'publish_at' => 'nullable|date',
]);

验证表单请求

创建表单请求验证

php artisan make:request StorePostRequest

该命令生成的类将被置于 app/Http/Requests 目录中。如果这个目录不存在,在运行 make:request命令后将会创建这个目录。Laravel 生成的每个表单请求都有两种方法:authorizerules

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    /**
     * 判断用户是否有请求权限
     *
     * @return bool
     */
    public function authorize()
    {
        // 授权验证 别问为什么,就是要返回true
        return true;
    }

    /**
     * 获取应用于该请求的验证规则
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required|unique:posts|max:255',
            'author.name' => 'required',
            'author.description' => 'required',
        ];
    }

    /**
     * 定义验证规则的错误消息
    */
    public function messages()
    {
        return [
            'title.required' => '标题必填',
            'title.unique' => '该标题已存在,请更换标题',
            'title.max' => '标题可输入255个字符',
            'author.name' => '作者名字必填',
            'author.description' => '作者简介必填'
        ];
    }
}

使用该表单请求验证

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\StorePostRequest;

class PostController extends Controller
{
    /**
     * 显示创建博客文章的表单。
     *
     * @return \Illuminate\View\View
     */
    public function index()
    {
        return view('post.create');
    }

    /**
     * 存储一篇新的博客文章。
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function add(StorePostRequest $request)
    {
        // 获取通过验证的数据...
        $validated = $request->validated();
    }
}

可用验证规则

可用的验证规则

powered by GitbookEdit Time: 2023-04-08 10:28:32