为你的 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 相关文章推荐
c#中的实现php中的preg_replace
Dec 21 PHP
php中使用Curl、socket、file_get_contents三种方法POST提交数据
Aug 12 PHP
PHP获取搜索引擎关键字来源的函数(支持百度和谷歌等搜索引擎)
Oct 03 PHP
PHP中Header使用的HTTP协议及常用方法小结
Nov 04 PHP
支持中文的PHP按字符串长度分割成数组代码
May 17 PHP
PHP汉字转换拼音的函数代码
Dec 30 PHP
Linux安装配置php环境的方法
Jan 14 PHP
PHP数组游标实现对数组的各种操作详解
Jan 26 PHP
PHP实现自动识别原编码并对字符串进行编码转换的方法
Jul 13 PHP
php微信公众平台示例代码分析(二)
Dec 06 PHP
浅谈PHP各环境下的伪静态配置
Mar 13 PHP
php与阿里云短信接口接入操作案例分析
May 27 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 开发环境配置(Zend Studio)
2010/04/28 PHP
php 随机排序广告的实现代码
2011/05/09 PHP
PHP注释语法规范与命名规范详解篇
2018/01/21 PHP
JS中toFixed()方法引起的问题如何解决
2012/11/20 Javascript
jquery实现弹出div,始终显示在屏幕正中间的简单实例
2014/03/08 Javascript
JS和css实现检测移动设备方向的变化并判断横竖屏幕
2015/05/25 Javascript
使用Javascript写的2048小游戏
2015/11/25 Javascript
JS中split()用法(将字符串按指定符号分割成数组)
2016/10/24 Javascript
vue.js 使用v-if v-else发现没有执行解决办法
2017/05/15 Javascript
JS实现数组去重方法总结(六种方法)
2017/07/14 Javascript
Vue 组件封装 并使用 NPM 发布的教程
2018/09/30 Javascript
小程序点击图片实现自动播放视频
2020/05/29 Javascript
JavaScript 斐波那契数列 倒序输出 输出100以内的质数代码实例
2019/09/11 Javascript
VUE中V-IF条件判断改变元素的样式操作
2020/08/09 Javascript
python在多玩图片上下载妹子图的实现代码
2013/08/13 Python
python实现无证书加密解密实例
2014/10/27 Python
python实现简易内存监控
2018/06/21 Python
Python嵌套列表转一维的方法(压平嵌套列表)
2018/07/03 Python
python给微信好友定时推送消息的示例
2019/02/20 Python
Python3实现的简单三级菜单功能示例
2019/03/12 Python
python关闭占用端口方式
2019/12/17 Python
阿迪达斯加拿大官网:Adidas加拿大
2016/08/25 全球购物
世界著名的顶级牛排:Omaha Steak(奥马哈牛排)
2016/09/20 全球购物
世界领先的高品质定制产品平台:Zazzle
2017/07/23 全球购物
英国最大的在线时尚眼镜店:Eyewearbrands
2019/03/12 全球购物
中国领先的汽车保养服务平台:途虎养车
2019/10/18 全球购物
俄罗斯鲜花递送:AMF
2020/04/24 全球购物
一些PHP的面试题
2015/05/06 面试题
个人简历自我鉴定
2013/10/11 职场文书
财产公证书格式
2014/04/10 职场文书
入党积极分子学习优秀共产党员先进事迹思想汇报
2014/09/13 职场文书
政协工作总结2015
2015/05/20 职场文书
HTML基础-标签分类(闭合标签,空标签,块级元素,行内元素,行级块元素,可替换元素)
2021/03/31 HTML / CSS
python必学知识之文件操作(建议收藏)
2021/05/30 Python
Redis做数据持久化的解决方案及底层原理
2021/07/15 Redis
vue css 相对路径导入问题级踩坑记录
2022/06/05 Vue.js