• 为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);
  • 相关阅读:
    HTML图片映射
    js数组去重问题
    Mooc--五子棋(js)小结
    js跨域问题
    HTML5新特性
    js输出
    CSS display属性学习
    理财课堂日记第1天
    磁盘性能测试方法
    一个清空数据库数据的脚本总结
  • 原文地址:https://www.cnblogs.com/cgjcgs/p/5490230.html
Copyright © 2020-2023  润新知