为你的 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 相关文章推荐
解析左右值无限分类的实现算法
Jun 20 PHP
php遍历目录输出目录及其下的所有文件示例
Jan 27 PHP
PHP实现对png图像进行缩放的方法(支持透明背景)
Jul 15 PHP
ThinkPHP数据操作方法总结
Sep 28 PHP
判断、添加和删除WordPress置顶文章的相关PHP函数小结
Dec 10 PHP
浅谈PHP的exec()函数无返回值排查方法(必看)
Mar 31 PHP
PHP Post获取不到非表单数据的问题解决办法
Feb 27 PHP
PHP观察者模式示例【Laravel框架中有用到】
Jun 15 PHP
实例讲解PHP验证邮箱是否合格
Jan 28 PHP
PHP addslashes()函数讲解
Feb 03 PHP
PHP fprintf()函数用法讲解
Feb 16 PHP
tp5.1 框架数据库高级查询技巧实例总结
May 25 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
如何使用PHP获取网络上文件
2006/10/09 PHP
Mysql的GROUP_CONCAT()函数使用方法
2008/03/28 PHP
php学习笔记 类的声明与对象实例化
2011/06/13 PHP
PHP __autoload函数(自动载入类文件)的使用方法
2012/02/04 PHP
深入PHP操作MongoDB的技术总结
2013/06/02 PHP
PHP面向对象多态性实现方法简单示例
2017/09/27 PHP
javascript开发技术大全 第4章 直接量与字符集
2011/07/03 Javascript
利用js实现选项卡的特别效果的实例
2013/03/03 Javascript
简单谈谈json跨域
2016/03/13 Javascript
深入理解事件冒泡(Bubble)和事件捕捉(capture)
2016/05/28 Javascript
canvas仿iwatch时钟效果
2017/03/06 Javascript
AngularJS通过ng-Img-Crop实现头像截取的示例
2017/08/17 Javascript
vue组件watch属性实例讲解
2017/11/07 Javascript
node前端模板引擎Jade之标签的基本写法
2018/05/11 Javascript
发布Angular应用至生产环境的方法
2018/12/10 Javascript
Vue传参一箩筐(页面、组件)
2019/04/04 Javascript
详解es6新增数组方法简便了哪些操作
2019/05/09 Javascript
ES6 Promise对象的应用实例分析
2019/06/27 Javascript
[01:31:03]DOTA2完美盛典全回顾 见证十五项大奖花落谁家
2017/11/28 DOTA
[01:05:41]EG vs Optic Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
Python 文件操作实现代码
2009/10/07 Python
Python3.6连接Oracle数据库的方法详解
2018/05/18 Python
python 划分数据集为训练集和测试集的方法
2018/12/11 Python
基于Python实现迪杰斯特拉和弗洛伊德算法
2020/05/27 Python
python 实现图片旋转 上下左右 180度旋转的示例
2019/01/24 Python
使用Python画出小人发射爱心的代码
2019/11/23 Python
tensorflow中tf.slice和tf.gather切片函数的使用
2020/01/19 Python
10个python3常用排序算法详细说明与实例(快速排序,冒泡排序,桶排序,基数排序,堆排序,希尔排序,归并排序,计数排序)
2020/03/17 Python
Python ADF 单位根检验 如何查看结果的实现
2020/06/03 Python
python pip如何手动安装二进制包
2020/09/30 Python
马来西亚最大的电器网站:Senheng
2017/10/13 全球购物
For Art’s Sake官网:手工制作的奢华眼镜
2018/12/15 全球购物
请写出char *p与"零值"比较的if语句
2014/09/24 面试题
医院检讨书范文
2014/02/01 职场文书
你真的了解PHP中的引用符号(&)吗
2021/05/12 PHP
nginx代理实现静态资源访问的示例代码
2022/07/07 Servers