Laravel 验证教程:控制器、表单请求和验证规则

Laravel

任何一个项目的核心部分都是了解如何验证用户的请求。在本教程中,我们将了解如何通过控制器、FormRequest 和 Rules 中验证用户的请求。

控制器

默认情况下,所有 Laravel 控制器都继承于 ValidatesRequests trait

ValidatesRequests trait 允许您使用可以在控制器中使用 validate 方法。

例如, 加入用户正在创建一篇文章:

他可能会输入文章标题、一些文章内容以及发布日期,您的控制器可能像下面这些这样处理,这些方法都是有效的:

public function store(Request $request) {
    $this->validate($request, [
        'name' => 'required|string',
        'body' => 'required|string',
        'publish_at' => 'required|date_format:Y-m-d H:i:s'
    ]);

    // 请求验证通过,代码继续执行
    ...
}

public function store(Request $request) {
    // Note: the array syntax is also available
    $request->validate([
      'name' => ['required', 'string'],
      'body' => ['required', 'string'],
      'publish_at' => ['required', 'date_format:Y-m-d H:i:s'],
    ]);

    // 请求验证通过,代码继续执行
    ...
}

public function store() {
    request()->validate([
      // Validation Rules...
    ]);

    // 请求验证通过,代码继续执行
    ...
}

public function store() {
    $this->validate(request(), [
      // 一些验证规则...
    ]);

    // 请求验证通过,代码继续执行
    ...
}

还应注意的是, validate 方法返回的是验证通过的数据:

public function store(Request $request) {
    $validatedData = $request->validate([
      'name' => ['required', 'string'],
      'body' => ['required', 'string'],
      'publish_at' => ['required', 'date_format:Y-m-d H:i:s'],
    ]);

    // 验证规则的 key 必须是唯一的才能验证成功,例如: name, body, published_at
    $this->articleService->store($validatedData);
}

您也可以现在选择这样做:

public function store(Request $request) {
    $request->validate([
      'name' => ['required', 'string'],
      'body' => ['required', 'string'],
      'publish_at' => ['required', 'date_format:Y-m-d H:i:s'],
    ]);

    // 验证规则的 Key 必须是唯一的才能验证成功,例如.: name, body, published_at
    $this->articleService->store($request->only('name', 'body', 'published_at'));
}

验证规则 可以找到所有可用的验证规则.

使用 FormRequest 验证

如果您想从控制器中提取出验证逻辑,或者想同时进行授权和验证,则可以使用 Laravel 的 Form Request 类。

您可以使用如下命令生成一个表单验证类:

php artisan make:request StoreArticleRequest

默认情况下会在 app/Http/Requests 中生成:

class StoreArticleRequest extends FormRequest
{

    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            //
        ];
    }
}

FormRequest 类拥有 authorizerules 方法。

鉴权

如果 Authorize 方法返回 False,那么控制器的代码将不会运行并且抛出 401 unauthorized 异常。

使用案例:

public function authorize()
{
    return $this->user()->can('create articles');
}

验证规则

rules 返回一个跟控制器中验证类似的规则数组;

public function rules()
{
    return [
      'name' => ['required', 'string'],
      'body' => ['required', 'string'],
      'publish_at' => ['required', 'date_format:Y-m-d H:i:s'],
    ];
}

注意: 你需要在需要验证的地方依赖注入这个类。

所以我们到底该怎么使用这个类呢? 只要在控制器中注入这个类即可:

public function store(StoreArticleRequest $request) {
    // 验证通过
}

如果验证失败,用户会被重定向到上一个页面并且会将错误信息闪存到session中,如果是一个 Ajax 请求的话,则会返回一个 422 Unprocessable 响应.

您可以像这样获取已经验证通过的数据:

public function store(StoreArticleRequest $request) {
    $validatedData = $request->validated();

    // 插入数据库
    ...
}

使用自定义规则类验证

如果您的验证规则没有在可用的内建规则中,您可以自定义一个:

使用 Laravel 的 make 命令生成一个验证规则:

php artisan make:rule IsValidStateInUSA

默认会再 app/Rules 中生成:

class IsValidStateInUSA implements Rule
{

    public function passes($attribute, $value)
    {
        //
    }

    public function message()
    {
        return 'The validation error message.';
    }
}

您可以在 passes 方法中编写您的验证规则,在 message 方法中编写验证失败的提示信息。

要判断 是否是美国的某个州, 我们需要像这样录入 50 个不同州的代号:

class IsValidStateInUSA implements Rule
{

    public function passes($attribute, $value)
    {
        return in_array(strtoupper($value), [
          'AL',
          'AK',
          'AZ',
          ...
        ]);
    }

    public function message()
    {
        return '这不是美国的某个州';
    }
}

然后在您的控制器或者 FormRequest 中像这样使用它即可:

public function store(Request $request) {
    $request->validate([
      'state' => ['required', new IsValidStateInUSA],
    ]);

    ...
}

处理验证错误

当验证失败时, Laravel 会自动重定向回上一个页面, 并且在 session 中携带$errors 变量。

您可以轻松的创建一个名为 messages.blade.php 的文件,并且继承布局文件:

@if($errors->any())
    <div class="alert alert-danger" role="alert">
        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
            <span aria-hidden="true">×</span>
        </button>

        @foreach($errors->all() as $error)
            {{ $error }}<br/>
        @endforeach
    </div>
@endif

这样可以显示 session 中的所有错误, 如果您想要一个一个处理错误的话,可以使用 blade 模板提供的 @error 方法:

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

$message 变量会在 @error 标签中定义。

自定义错误提示

使用 validate 方法时, 可以传入第三个参数重写 messages :

public function store(Request $request) {
    $this->validate($request, [
        'name' => 'required|string',
        'body' => 'required|string',
        'publish_at' => 'required|date_format:Y-m-d H:i:s'
    ], [
      'name.required' => '文章名称必填',
      'body.required'  => '文章正文必填',
      'publish_at.date_format' => '发布日期格式错误'
    ]);

    // 请求通过i,继续运行
    ...
}

使用 FormRequest 类时, messages 方法可以自定义消息提示:

public function messages()
{
    return [
        'name.required' => '文章名称必填',
        'body.required'  => '文章正文必填',
        'publish_at.date_format' => '发布日期格式错误'
    ];
}

想详细了解最新的验证相关的问题,请访问 Laravel文档.

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://laravel-news.com/laravel-validat...

译文地址:https://learnku.com/laravel/t/42925

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!