给个意见或建议吧

扩展一个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. JQuery基础一

    1.在浏览器点击F12,调出源码设置端点F11进行调试 2.要操作DOM对象,首先要把DOM对象封装成juery对象: jQuery(document).ready(function () { ale ...

  2. shell调试

    sh -x set -x 中间是要调试的代码 set +x

  3. [转] GitHub上README.md教程

    点击阅读原文 最近对它的README.md文件颇为感兴趣.便写下这贴,帮助更多的还不会编写README文件的同学们. README文件后缀名为md.md是markdown的缩写,markdown是一种 ...

  4. 完整成功配置wamp server小记

    首先安装最新版本的wamp server,这是必须的! 配置默认”www目录”的路径(可选):下面以改为D:\site为例.打开wamp\scripts\config.inc.php第47行,$www ...

  5. python学习之安装模块

    安装pip下载python模块 yum -y install python-pip pip install pandas (pandas要安装的模块名) 默认使用的官方python源,这个在国内访问很 ...

  6. HDU 4048 Zhuge Liang's Stone Sentinel Maze

    Zhuge Liang's Stone Sentinel Maze Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/327 ...

  7. 【MySQL】MySQL快速插入大量数据

    起源 在公司优化SQL遇到一个索引的问题,晚上回家想继续验证,无奈没有较多数据的表,于是,想造一些随机的数据,用于验证. 于是 于是动手写.由于自己不是MySQL能手,写得也不好.最后,插入的速度也不 ...

  8. [问题2014S01] 复旦高等代数II(13级)每周一题(第一教学周)

    问题2014S01  设 \(f(x_1,x_2,\cdots,x_n)\) 是次数等于 2 的 \(n\) 元实系数多项式, \(S\) 是使得 \(f(x_1,x_2,\cdots,x_n)\) ...

  9. hadoop2.0初识1.2

    1 hadoop启动方式(三种) 1.1 各个服务组件逐一启动 *dfs hadoop-daemon.sh start|stop namenode|datanode|secondarynamenode ...

  10. consul模板配置参数值示例

    参看https://github.com/hashicorp/consul-template#examples // This is the address of the Consul agent. ...