为speedphp最新版添加 仿Yii 的简易版 数据验证 支持不同场景,自定义回调
给个意见或建议吧
扩展一个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 的简易版 数据验证 支持不同场景,自定义回调的更多相关文章
- 仿vue实现简易版mvvm双向绑定
项目地址:https://github.com/pangyongsheng/mvvm 1. 指令 vm-bind 单选数据绑定- 将数据显示到标签视图 vm-model : 双向数据绑定 vm-sho ...
- 《IT蓝豹》高仿花田ios版标签移动效果
高仿花田ios版标签移动效果,长按每一个item拖动到自己想要位置后,后面位置移动补全效果 . 本项目适合研究gridview拖拽效果的朋友下载. 学习android动画特效. 本项目主要靠DragG ...
- 仿百度壁纸客户端(一)——主框架搭建,自定义Tab+ViewPager+Fragment
仿百度壁纸客户端(一)--主框架搭建,自定义Tab+ViewPager+Fragment 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment ...
- CSDN新版Markdown编辑器(Alpha 2.0版)使用示例(文首附源码.md文件)
CSDN新版Markdown编辑器(Alpha 2.0版) 使用示例 附 本文的Markdown源码: https://github.com/yanglr/AlgoSolutions/blob/mas ...
- 为Azure Web Site 添加ADFS验证支持之二 在代码里使用ADFS
下面我们来创建一个MVC 5.0的ASP.Net程序,并且将它部署到Azure Web Site上 通过Visual Studio 2015创建Web Project 在选择ASP.net模板的地方, ...
- 为Azure Web Site 添加ADFS验证支持之一 设置ADFS的信任关系
很多时候企业开发的应用都会通过AD(Active Directory)进行验证用户名密码的,在企业里面统一一个AD来进行账号密码管理也是一个很好的实践.当企业打算将一个应用迁移到Azure的时候,使用 ...
- ROS Learning-019 learning_tf-03(编程) 添加额外的坐标系 (Python版)
ROS Indigo learning_tf-03 添加额外的坐标系 (Python版) 我使用的虚拟机软件:VMware Workstation 11 使用的Ubuntu系统:Ubuntu 14.0 ...
- JavaScript星级评分,仿百度,增强版
JavaScript星级评分,仿百度,增强版 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" & ...
- 为 ASP.NET Core (6.0)服务应用添加ApiKey验证支持
这个代码段演示了如何为一个ASP.NET Core项目中添加Apikey验证支持. 首先,通过下面的代码创建项目 dotnet new webapi -minimal -o yourwebapi 然后 ...
随机推荐
- Shadow Zhang PGPool 配置错误定位 s_do_auth: expecting R got E
自从按照教程 http://www.pgpool.net/docs/latest/pgpool-zh_cn.html#hba配置好PGPool以后,每次启动 pgpool -c -n -D 都报 s_ ...
- POJ 3436:ACM Computer Factory(最大流记录路径)
http://poj.org/problem?id=3436 题意:题意很难懂.给出P N.接下来N行代表N个机器,每一行有2*P+1个数字 第一个数代表容量,第2~P+1个数代表输入,第P+2到2* ...
- windows+caffe(三)——求取图片的均值
这个要在图片已经转化成lmdb格式下才能求均值... 1.查看caffe根目录下的bin是否存在compute_image_mean.exe(用的happey大神的) 如果没有存在,你需要打开Main ...
- mysql数据库的一些用法
mysql数据库语句 1.replace into REPLACE INTO (列名1,列名2,列名3) VALUES ('值1','值2','值3'); # 如果数据库中不存在 ...
- JavaIO总结
Java IO流分为字节流和字符流 下面首先介绍一下字节流 /** * 字节流测试 * @author hc * */ public class Test { public static void m ...
- 阻抗计算公式、polar si9000(教程)
给初学者的一直有很多人问我阻抗怎么计算的. 人家问多了,我想给大家整理个材料,于己于人都是个方便.如果大家还有什么问题或者文档有什么错误,欢迎讨论与指教!在计算阻抗之前,我想很有必要理解这儿阻抗的意义 ...
- 一个通用的DataGridView导出Excel扩展方法(支持列数据格式化)
假如数据库表中某个字段存放的值“1”和“0”分别代表“是”和“否”,要在DataGridView中显示“是”和“否”,一般用两种方法,一种是在sql中直接判断获取,另一种是在DataGridView的 ...
- 深入浅出设计模式——原型模式(Prototype Pattern)
模式动机在面向对象系统中,使用原型模式来复制一个对象自身,从而克隆出多个与原型对象一模一样的对象.在软件系统中,有些对象的创建过程较为复杂,而且有时候需要频繁创建,原型模式通过给出一个原型对象来指明所 ...
- Nginx模块之————RTMP模块的FFmpeg的配置问题是FFmpeg的连续退出
rtmp { server { listen ; application live { allow publish all; allow play all; live on; exec /root/b ...
- tomcat配置项目的图片路径不在项目下的处理
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWA ...