为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 然后 ...
随机推荐
- Windows消息传递机制详解
Windows是一个消息(Message)驱动系统.Windows的消息提供了应用程序之间.应用程序与Windows系统之间进行通信的手段.应用程序想要实现的功能由消息来触发,并且靠对消息的响应和处理 ...
- idea集成git
这几天刚刚用了idea编辑器.用起来感觉相比eclipse有很大优势.其中我觉得特别引人注意的一个优势就是与git的集成开发.git作为一个代码维护的平台和idea结合使用对团队开发有很大意义.本人是 ...
- JavaScript脚本语言基础(四)
导读: JavaScript和DOM DOM文档对象常用方法和属性 DOW文档对象运用 JSON数据交换格式 正则表达式 1.JavaScript和DOM [返回] 文档对象模型(Document O ...
- (2) 深入理解Java Class文件格式(一)
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/21486985 Class文件在Java体系结构中的位置和作用 在上一篇博客中, 大致讲 ...
- SpringMvc xml 配置
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" ...
- python 列表常用操作
例子: list1 = [1, 2, 3, 4, 5, 6, [6, 7, 8,9], 'hi', 'hello', 6] list2 = [7, 8, 1, 2] list3 = ['good', ...
- Xcode代码提示联想功能失效,按command键点不进去类库,提示“?”
参考文档:这两篇文章很好的解决了问题.可以很好的解决了问题 Xcode代码提示联想功能失效,按command键点不进去类库,提示“?”,代码全是白色 Xcode4中代码补全(Code Completi ...
- BW常用事务码Tcode
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 安装了ubuntu14.04+windows7双系统的笔记本启动后出现grub rescue>提示符
解决思想如下: 1.在grub rescue>提示符处输入ls 即可看到该命令列出了硬盘上的所有分区,找到安装了linux的分区,我的安装在(hd0,msdos8)下,所以我以(hd0,msd ...
- 用HttpSessionListener与HttpSessionBindingListener实现在线人数统计
在线人数统计方面的实现,最初我的想法是,管理session,如果session销毁了就减少,如果登陆用户了就新增一个,但是如果是用户非法退出,如:未注销,关闭浏览器等,这个用户的session是管理不 ...