为你的 Laravel 验证器加上多验证场景的实现


Posted in PHP onApril 07, 2020

前言

在我们使用 laravel 框架的验证器,有的时候需要对表单等进行数据验证,当然 laravel 也为我们提供了
Illuminate\Http\Request 对象提供的 validate 方法 以及 FormRequest 和 Validator。

FormRequest 通过新建文件将我们的验证部分单独分开,来避免控制器臃肿。如果验证失败,就会生成一个让用户返回到先前的位置的重定向响应。这些错误也会被闪存到 Session 中,以便这些错误都可以在页面中显示出来。如果传入的请求是 AJAX,会向用户返回具有 422 状态代码和验证错误信息的 JSON 数据的 HTTP 响应。如果是接口请求或 ajax, 那么我们可能还需要将返回的 json 数据修改成我们想要的格式。

当我们实际开发中,可能一个模块需要有多个验证场景,如果为每一个验证场景都新建一个 FormRequest 不就太过繁琐了。
那么给 laravel 加上一个验证场景通过一个验证类一个模块或多个模块来适应不同的场景不就方便很多了。

开始

首先 我们封装了一个基类 BaseValidate.php 并将其放在 app\Validate 下,当然你也可以放在其他地方,只要修改好命名空间就好。

<?php
namespace App\Validate;

use Illuminate\Support\Facades\Validator;
/**
 * 扩展验证器
 */
class BaseValidate {

  /**
   * 当前验证规则
   * @var array
   */
  protected $rule = [];

  /**
   * 验证提示信息
   * @var array
   */
  protected $message = [];

  /**
   * 验证场景定义
   * @var array
   */
  protected $scene = [];

  /**
   * 设置当前验证场景
   * @var array
   */
  protected $currentScene = null;

  /**
   * 验证失败错误信息
   * @var array
   */
  protected $error = [];

  /**
   * 场景需要验证的规则
   * @var array
   */
  protected $only = [];


  /**
   * 设置验证场景
   * @access public
   * @param string $name 场景名
   * @return $this
   */
  public function scene($name)
  {
    // 设置当前场景
    $this->currentScene = $name;

    return $this;
  }

  /**
   * 数据验证
   * @access public
   * @param array   $data 数据
   * @param mixed   $rules 验证规则
   * @param array  $message 自定义验证信息
   * @param string  $scene 验证场景
   * @return bool
   */
  public function check($data, $rules = [], $message = [],$scene = '')
  {
    $this->error =[];
    if (empty($rules)) {
      //读取验证规则
      $rules = $this->rule;
    }
    if (empty($message)) {
      $message = $this->message;
    }

    //读取场景
    if (!$this->getScene($scene)) {
      return false;
    }

    //如果场景需要验证的规则不为空
    if (!empty($this->only)) {
      $new_rules = [];
      foreach ($this->only as $key => $value) {
        if (array_key_exists($value,$rules)) {
          $new_rules[$value] = $rules[$value];
        }  
      }
      $rules = $new_rules;
    }
    // var_dump($rules);die;
    $validator = Validator::make($data,$rules,$message);
    //验证失败
    if ($validator->fails()) {
      $this->error = $validator->errors()->first();
      return false;
    }

    return !empty($this->error) ? false : true;
  }

  /**
   * 获取数据验证的场景
   * @access protected
   * @param string $scene 验证场景
   * @return void
   */
  protected function getScene($scene = '')
  {
    if (empty($scene)) {
      // 读取指定场景
      $scene = $this->currentScene;
    }
    $this->only = [];

    if (empty($scene)) {
      return true;
    }

    if (!isset($this->scene[$scene])) {
      //指定场景未找到写入error
      $this->error = "scene:".$scene.'is not found';
      return false;
    }
    // 如果设置了验证适用场景
    $scene = $this->scene[$scene];
    if (is_string($scene)) {
      $scene = explode(',', $scene);
    }
    //将场景需要验证的字段填充入only
    $this->only = $scene;
    return true;
  }

  // 获取错误信息
  public function getError()
  {
    return $this->error;
  } 
}

使用

接下来我们来验证一个文章的提交信息,首先我们新建一个文章验证类 ArticleValidate.php 并填充一些内容

<?php
namespace App\Validate;

use App\Validate\BaseValidate;
/**
 * 文章验证器
 */
class ArticleValidate extends BaseValidate {
  //验证规则
  protected $rule =[
    'id'=>'required',
    'title' => 'required|max:255',
    'content' => 'required',
  ];
  //自定义验证信息
  protected $message = [
    'id.required'=>'缺少文章id',
    'title.required'=>'请输入title',
    'title.max'=>'title长度不能大于 255',
    'content.required'=>'请输入内容',
  ];

  //自定义场景
  protected $scene = [
    'add'=>"title,content",
    'edit'=> ['id','title','content'],
  ];
}

如上所示,在这个类中我们定义了验证规则 rule,自定义验证信息 message,以及验证场景 scene

非场景验证

我们只需要定义好规则

public function update(){

    $ArticleValidate = new ArticleValidate;

    $request_data = [
      'id'=>'1',
      'title'=>'我是文章的标题',
      'content'=>'我是文章的内容',
    ];

    if (!$ArticleValidate->check($request_data)) {
      var_dump($ArticleValidate->getError());
    }
  }

check 方法中总共有四个参数,第一个要验证的数据,第二个验证规则,第三个自定义错误信息,第四个验证场景,其中 2,3,4 非必传。
如果验证未通过我们调用 getError() 方法来输出错误信息,getError()暂不支持返回所有验证错误信息 。

场景验证

我们需要提前在验证类中定义好验证场景

如下,支持使用字符串或数组,使用字符串时,要验证的字段需用 , 隔开

//自定义场景
  protected $scene = [
    'add'=>"title,content",
    'edit'=> ['id','title','content'],
  ];

然后在我们的控制器进行数据验证

public function add(){

    $ArticleValidate = new ArticleValidate;

    $request_data = [
      'title'=>'我是文章的标题',
      'content'=>'我是文章的内容',
    ];

    if (!$ArticleValidate->scene('add')->check($request_data)) {
      var_dump($ArticleValidate->getError());
    }

  }

控制器内验证

当然我们也允许你不创建验证类来验证数据,

public function add(){

    $Validate = new BaseValidate;

    $request_data = [
      'title'=>'我是文章的标题',
      'content'=>'我是文章的内容',
    ];

    $rule =[
      'id'=>'required',
      'title' => 'required|max:255',
      'content' => 'required',
    ];
    //自定义验证信息
    $message = [
      'id.required'=>'缺少文章id',
      'title.required'=>'请输入title',
      'title.max'=>'title长度不能大于 255',
      'content.required'=>'请输入内容',
    ];

    if (!$Validate->check($request_data,$rule,$message)) {
      var_dump($Validate->getError());
    }
  }

通过验证场景,既减少了控制器代码的臃肿,又减少了 FormRequest 文件过多,还可以自定义 json 数据是不是方便多了呢,

参考文档

laravel 表单验证 :表单验证《Laravel 5.5 中文文档》
thinkphp 验证场景 :https://www.kancloud.cn/manual/thinkphp5_1/354104

到此这篇关于为你的 Laravel 验证器加上多验证场景的实现的文章就介绍到这了,更多相关Laravel 验证器内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

本文为杨攀遥原创文章,如若转载,无需和我联系,但请注明出处 [杨攀遥的博客]:https://www.yangpanyao.com/archives/120.html

PHP 相关文章推荐
php下检测字符串是否是utf8编码的代码
Jun 28 PHP
PHP 基本语法格式
Dec 15 PHP
php header示例代码(推荐)
Sep 08 PHP
php通过数组实现多条件查询实现方法(字符串分割)
May 06 PHP
php将12小时制转换成24小时制的方法
Mar 31 PHP
ThinkPHP里用U方法调用js文件实例
Jun 18 PHP
php判断是否连接上网络的方法实例详解
Dec 14 PHP
php批量删除操作代码分享
Feb 26 PHP
Thinkphp5结合layer弹窗定制操作结果页面
Jul 07 PHP
thinkphp5引入公共部分header、footer的方法详解
Sep 14 PHP
PHP pthreads v3下的Volatile简介与使用方法示例
Feb 21 PHP
详解thinkphp的Auth类认证
May 28 PHP
再谈Yii Framework框架中的事件event原理与应用
Apr 07 #PHP
Yii框架组件的事件机制原理与用法分析
Apr 07 #PHP
Yii框架多语言站点配置方法分析【中文/英文切换站点】
Apr 07 #PHP
php设计模式之适配器模式实例分析【星际争霸游戏案例】
Apr 07 #PHP
php设计模式之迭代器模式实例分析【星际争霸游戏案例】
Apr 07 #PHP
解决Laravel5.x的php artisan migrate数据库迁移创建操作报错SQLSTATE[42000]
Apr 06 #PHP
4种Windows系统下Laravel框架的开发环境安装及部署方法详解
Apr 06 #PHP
You might like
经典的星际争霸,满是回忆的BGM
2020/04/09 星际争霸
PHP 变量的定义方法
2010/01/26 PHP
php自定义错误处理用法实例
2015/03/20 PHP
PHP的PDO常用类库实例分析
2016/04/07 PHP
关于php中一些字符串总结
2016/05/05 PHP
PHP通过文件保存和更新信息的方法分析
2019/09/12 PHP
laravel-admin的图片删除实例
2019/09/30 PHP
Firebug 字幕文件JSON地址获取代码
2009/10/28 Javascript
jquery随意添加移除html的实现代码
2011/06/21 Javascript
jQuery基础框架浅入剖析
2012/12/27 Javascript
jquery数组封装使用方法分享(jquery数组遍历)
2014/03/25 Javascript
Javascript字符串对象的常用方法简明版
2014/06/26 Javascript
浅谈JavaScript实现面向对象中的类
2014/12/09 Javascript
JavaScript获取function所有参数名的方法
2015/10/30 Javascript
15个常用的jquery代码片段
2015/12/19 Javascript
AngularJS基础 ng-dblclick 指令用法
2016/08/01 Javascript
Vue 页面切换效果之 BubbleTransition(推荐)
2018/04/08 Javascript
详解vue中使用vue-quill-editor富文本小结(图片上传)
2019/04/24 Javascript
jQuery实现的点击显示隐藏下拉菜单功能完整示例
2019/05/17 jQuery
JavaScript仿京东秒杀倒计时
2020/03/17 Javascript
Javascript执行上下文顺序的深入讲解
2020/11/04 Javascript
使用BeautifulSoup爬虫程序获取百度搜索结果的标题和url示例
2014/01/19 Python
python中常用的各种数据库操作模块和连接实例
2014/05/29 Python
10种检测Python程序运行时间、CPU和内存占用的方法
2015/04/01 Python
Python3.x中自定义比较函数
2015/04/24 Python
浅谈python正则的常用方法 覆盖范围70%以上
2018/03/14 Python
python实现三次样条插值
2018/12/17 Python
Python算法中的时间复杂度问题
2019/11/19 Python
tornado+celery的简单使用详解
2019/12/21 Python
python3 字符串知识点学习笔记
2020/02/08 Python
Django修改app名称和数据表迁移方案实现
2020/09/17 Python
简单的JAVA编程面试题
2013/03/19 面试题
科室工作的个人自我评价
2013/10/30 职场文书
大学生安全责任书
2014/07/25 职场文书
初中同学会活动方案
2014/08/22 职场文书
毕业典礼主持词
2015/06/29 职场文书