给个意见或建议吧

扩展一个Model基类

<?php

class BaseModel extends Model{

    use ValidationRules;

    public function rules(){} 

}

/**
* 验证参数规则
*/
trait ValidationRules{ public $_data;
public $errors = []; // 验证产生的错误
public $scene = 'default'; // 场景 ['update','create']
private $ok = true; /**
* 验证数据
*/
public function validate($data){
if($this->errors) $this->errors = [];
$_rules = $this->rules();
$this->_data = $data;
if(!$_rules) return true;
if(!is_array($_rules)) throw new ErrorException('Model::rules必须为数组');
foreach($_rules as $key => $val){
$this->checkRow($val);
}
return $this->ok;
} public function addErrors($msg){
$this->errors[] = $msg;
} //检查一行
private function checkRow(&$row){
if(count($row) < 2 || !is_array($row)) throw new ErrorException('Model::rules格式错误');
if(isset($row['on']) && is_array($row['on']) && !in_array($this->scene,$row['on'])) return true; // 如果 on 不是array 或者不是当前的场景 则忽略 如果没定义on 则是公用的
if(is_array($row[0])){
foreach($row[0] as $k => $v){
$this->checkField($v,$row[1],$row);
}
}elseif(is_string($row[0])){
$this->checkField($row[0],$row[1],$row);
}else{
throw new ErrorException('Model::rules格式错误');
}
}
//检查一个字段
private function checkField($field,&$func,&$row){
if($func instanceof Closure){
!$func($field,$row) && $this->ok = false;
}elseif(is_string($func)){
if(!method_exists($this,$func)) throw new ErrorException('Model的方法:'.$func.' 不存在');
if( $func =='required' || (isset($this->_data[$field]) && $this->_data[$field] !='')){
!$this->$func($field,$row) && $this->ok = false;
}
}else{
throw new ErrorException('Model::rules格式错误');
}
} protected function required($field,&$row){ //必须的字段不能为空 其他的类型检查 可以为空(只有当有值且不符合规则的时候才为false)
if(isset($this->_data[$field])?$this->_data[$field]=='':true){
$this->addErrors($field.(isset($row['msg'])?$row['msg']:'不能为空'));
return false;
}
return true;
} protected function email($field,&$row){
if(!preg_match( "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i", $this->_data[$field])){
$this->addErrors($field.(isset($row['msg'])?$row['msg']:'格式错误'));
return false;
}
return $this->checkLength($field,$row);
} private function checkLength($field,&$row){
if(isset($row['max'])?mb_strlen($this->_data[$field]) > $row['max']:false){
$this->addErrors($field."不能超过{$row['max']}个字");
return false;
}
if(isset($row['min'])?mb_strlen($this->_data[$field]) < $row['min']:false){
$this->addErrors($field."不能少于{$row['min']}个字");
return false;
}
return true;
} protected function phone($field,&$row){
if(!preg_match("/^1[34578]\d{9}$/", $this->_data[$field])){
$this->addErrors($field.(isset($row['msg'])?$row['msg']:'格式错误'));
return false;
}
return true;
} protected function number($field,&$row){
if(!preg_match('/^\s*[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\s*$/', $this->_data[$field])){
$this->addErrors($field.(isset($row['msg'])?$row['msg']:'格式错误'));
return false;
}
return $this->checkLength($field,$row);
} protected function integer($field,&$row){
if(!preg_match('/^\s*[+-]?\d+\s*$/', $this->_data[$field])){
$this->addErrors($field.(isset($row['msg'])?$row['msg']:'格式错误'));
return false;
}
return $this->checkLength($field,$row);
} protected function string($field,&$row){
if (!is_string($this->_data[$field])) {
$this->addErrors($field.(isset($row['msg'])?$row['msg']:'格式错误'));
return false;
}
return $this->checkLength($field,$row);
} protected function files(){
// 'ext' 'maxSize',max , Multiple
} protected function identical($field,&$row){ //一致
if(!isset($row['field'])) throw new ErrorException('Model::identical必须定义field');
if ($this->_data[$field] != $this->_data[$row['field']]){
$this->addErrors($field.(isset($row['msg'])?$row['msg']:"与{$row['field']}不一致"));
return false;
}
return true;
} }

model中覆盖rules方法

<?php
class User extends BaseModel{ public $table_name = "user"; public function rules(){
// required email phone number integer string identical
return [
[['username','password'],'required'],
['password2','required','on'=>['create']],
['email','email','msg'=>'邮箱错了','max'=>50],
['phone','phone'],
['phone','required','on'=>['update']],
['score','number'],
['tags',function($field,$row){
if(!isset($this->_data[$field]) || !is_array($this->_data[$field])){
$this->addErrors($field.(isset($row['msg'])?$row['msg']:'格式错误'));
return false;
}
return true
}],
['age','integer'],
[['username','password'],'string','max'=>32,'min'=>6],
['password2','identical','field'=>'password'],
]; } }

Controller中调用

$model = new User();
$model->scene = 'update';
// $a = $model->validate(['username'=>'admin1','password'=>'123456','email'=>'admin@163.com','phone'=>'14526396857','score'=>2.0,'age'=>2,'password2'=>'123456']);
$a = $model->validate([]);
var_dump($a);
print_r($model->errors);

为speedphp最新版添加 仿Yii 的简易版 数据验证 支持不同场景,自定义回调的更多相关文章

  1. 仿vue实现简易版mvvm双向绑定

    项目地址:https://github.com/pangyongsheng/mvvm 1. 指令 vm-bind 单选数据绑定- 将数据显示到标签视图 vm-model : 双向数据绑定 vm-sho ...

  2. 《IT蓝豹》高仿花田ios版标签移动效果

    高仿花田ios版标签移动效果,长按每一个item拖动到自己想要位置后,后面位置移动补全效果 . 本项目适合研究gridview拖拽效果的朋友下载. 学习android动画特效. 本项目主要靠DragG ...

  3. 仿百度壁纸客户端(一)——主框架搭建,自定义Tab+ViewPager+Fragment

    仿百度壁纸客户端(一)--主框架搭建,自定义Tab+ViewPager+Fragment 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment ...

  4. CSDN新版Markdown编辑器(Alpha 2.0版)使用示例(文首附源码.md文件)

    CSDN新版Markdown编辑器(Alpha 2.0版) 使用示例 附 本文的Markdown源码: https://github.com/yanglr/AlgoSolutions/blob/mas ...

  5. 为Azure Web Site 添加ADFS验证支持之二 在代码里使用ADFS

    下面我们来创建一个MVC 5.0的ASP.Net程序,并且将它部署到Azure Web Site上 通过Visual Studio 2015创建Web Project 在选择ASP.net模板的地方, ...

  6. 为Azure Web Site 添加ADFS验证支持之一 设置ADFS的信任关系

    很多时候企业开发的应用都会通过AD(Active Directory)进行验证用户名密码的,在企业里面统一一个AD来进行账号密码管理也是一个很好的实践.当企业打算将一个应用迁移到Azure的时候,使用 ...

  7. ROS Learning-019 learning_tf-03(编程) 添加额外的坐标系 (Python版)

    ROS Indigo learning_tf-03 添加额外的坐标系 (Python版) 我使用的虚拟机软件:VMware Workstation 11 使用的Ubuntu系统:Ubuntu 14.0 ...

  8. JavaScript星级评分,仿百度,增强版

    JavaScript星级评分,仿百度,增强版 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" & ...

  9. 为 ASP.NET Core (6.0)服务应用添加ApiKey验证支持

    这个代码段演示了如何为一个ASP.NET Core项目中添加Apikey验证支持. 首先,通过下面的代码创建项目 dotnet new webapi -minimal -o yourwebapi 然后 ...

随机推荐

  1. Linq To Sqlite 一一二二

    说在前头 之所以写下这些文字,主要是因为使用LINQ的同志们都觉它的美好(至于有多美好,各位心里知道,我就不在描述了,如果你是你还不了解LINQ,园子里有大把的文章),微软老哥只提供了自家的SQLSe ...

  2. Android PullToRefresh (GridView 下拉刷新上拉加载)

    做这个需要自己去git hub上下载个pull-to-refresh 里面有个library为依赖包自己导到自己的项目中 (下载地址:https://github.com/chrisbanes/And ...

  3. jQuery表单验证插件——jquery.validate.js

    官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation 一.导入js库 <script src="../j ...

  4. <Interview problem>二进制加法

    闲来无事,搜集一些有趣的面试题,以及解决方案,有些代码可能会自己写, 有些网上有比较完整的方案了,就直接把代码拷贝过来,描述一下解题思路. Given two binary strings, retu ...

  5. Object类型与Array类型

    总结--JS中的引用类型: Object类型,Array类型,Boolean类型,Number类型,String类型,Date类型, Function类型,RegExp类型,单体内置对象(Global ...

  6. GMF:如何在不打开Editor的情况下生成图片

    问题 GMF应用中,有时我们希望在不打开*DiagramEditor的情况下,从文件就能生成它的图片   解决方案 首先,从文件中构造DiagramImpl实例: TransactionalEditi ...

  7. Code First Migrations更新数据库结构(数据迁移)

    背景 code first起初当修改model后,要持久化至数据库中时,总要把原数据库给删除掉再创建 (DropCreateDatabaseIfModelChanges),此时就会产生一个问题,当我们 ...

  8. 理解JS回调函数

    我们经常会用到客户端与Web项目结合开发的需求,那么这样就会涉及到在客户端执行前台动态脚本函数,也就是函数回调,本文举例来说明回调函数的过程. 首先创建了一个Web项目,很简单的一个页面,只有一个bu ...

  9. C#程序设计---->计算圆面积windows程序

    值得说的就是添加一个回车事件, http://blog.csdn.net/nanwang314/article/details/6176604 private void textBox1_KeyDow ...

  10. (二)Kafka动态增加Topic的副本(Replication)

    (二)Kafka动态增加Topic的副本(Replication) 1. 查看topic的原来的副本分布 [hadoop@sdf-nimbus-perf ~]$ le-kafka-topics.sh ...