为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);
上一篇:App竞品技术分析 (3)减小安装包的体积(转)


下一篇:MVC3 Razor视图引擎的基础语法