Z-PHP数据验证类 validation.class.php

分享 未结
4 302
番茄
番茄 VIP 1 2018-04-02
悬赏:0

此类根据官方 core/lib/ext/verify.class.php 结合个人使用习惯修改而成

验证器类: common\lib\validation.class.php

<?php
/**
自动验证类
在模型文件中定义名为$roles的验证规则
protected $roles = array(
'nickname' => array(
'notnull' => array('both', '请填写昵称!',[$params]),
'length'  => array('add', '昵称 长度必须在5-16 之间',[$params]),
'unique'  => array('update', '昵称已存在!', [$params]),
),
);

//在模型文件中自定义验证方法的约定:
1.验证方法命名必须以check_开头
2.最多接受2个参数,$value为要验证的值,$params参数视情况使用,多个值使用数组传递
3.只返回true或false
4.多利用$valid_timing、$valid_data成员属性
protected function check_age($value,[$params]){
if($value < 1 || $value > 100) { return false; }else{ return true; }
}
 */
namespace lib;

use \z\db;

class validation extends db
{
    //验证时机
    protected $valid_timing;
    //要验证的数据
    protected $valid_data;

    /**
     * [create 主动验证]
     * @param  string  $data [待验证的数据]
     * @param  string  $timing ['add':添加数据时验证,'update':更新数据时验证,'both':添加和更新数据时都验证]
     * @return boolean
     */
    public function create($data = null, $timing = 'both')
    {
        if (empty($this->roles)) {return true;}
        if (empty($data)) {$data = $_POST;}
        $this->valid_data   = $data;
        $this->valid_timing = $timing;
        $true_count         = 0;
        foreach ($this->roles as $field => &$role) {
            $must = false;
            if (isset($role['must'])) {
                $must = $role['must'];
                unset($role['must']);
            }

            if (!isset($data[$field]) && !$must) {
                //表单数据无此项 且 验证规则must不为true 验证通过
                $true_count++;
            } elseif ($this->check_role($role, $data[$field])) {
                $true_count++;
            }
        }
        return $true_count == count($this->roles);
    }

    /**
     * 验证一个字段的规则
     * @param  array   $role  验证规则
     * @param  string  $value 字段值
     * @return boolean
     */
    private function check_role($role, $value)
    {
        $true_count = 0;
        foreach ($role as $role_name => &$role_value) {
            $role_timing = $role_value[0];
            if ($role_timing != $this->valid_timing and $role_timing != 'both') {
                $true_count++;
            } else {
                $role_errmsg  = $role_value[1];
                $role_params  = isset($role_value[2]) ? $role_value[2] : null;
                $check_method = 'check_' . $role_name;

                $ret = call_user_func(array($this, $check_method), $value, $role_params);
                if ($ret) {
                    $true_count++;
                } else {
                    parent::$dberror[] = $role_errmsg;
                    break; //有一个为假就停止验证
                }
            }
        }
        return $true_count == count($role);
    }

    #验证唯一值
    /**
     * 验证是否唯一值
     * @param $value第一个参数为要验证的值;
     * @param $key = func_get_arg(1) = 字段名;
     * @return boolean
     */
    private function check_unique($value)
    {
        $params = func_get_arg(1);
        $key    = is_array($params) ? $params[0] : $params;
        if (!$key) {
            parent::$dberror[] = 'check_unique参数错误';
            return false;
        }

        if ('update' == $this->valid_timing) {
            $pre  = $this->exe();
            $data = $pre->fetch(\PDO::FETCH_ASSOC);
            if ($data[$key] == $value) {
                return true;
            }
        }

        $bind_key        = ':' . $key;
        $bind[$bind_key] = $value;

        $sql = 'SELECT * FROM ' . $this->table . ' WHERE `' . $key . '`=' . $bind_key;
        $pre = self::db()->prepare($sql);

        $pre->execute($bind);
        if ($pre->fetch(\PDO::FETCH_ASSOC)) {
            return false;
        } else {
            return true;
        }
    }

    #验证是否为空
    /**
     * 验证是否为空
     * @param $value要验证的值
     * @return boolean
     */
    public static function check_notnull($value)
    {
        if ($value == '') {
            return false;
        } else {
            return true;
        }
    }

    #验证长度
    /**
     * 验证值的长度
     * @param $value第一个参数为要验证的值
     * @param $params = func_get_arg(1) $params[0] 最小值,$params[1] 最大值
     * @return boolean
     */
    public static function check_length($value)
    {
        $params = func_get_arg(1);
        if (!is_array($params)) {
            dump_file('check_length params error', 'validation_error.html');
        }
        $min    = $params[0];
        $max    = $params[1];
        $length = mb_strlen($value, 'UTF-8'); //兼容中文
        if ($length < $min || $length > $max) {
            return false;
        } else {
            return true;
        }
    }

    #验证邮箱
    /**
     * 验证是否是邮箱
     * @param $value为要验证的值
     * @return boolean
     */
    public static function check_email($value)
    {
        $preg = '/^[\w\.\-]+@[\w\-]+(\.\w+)+$/';
        return preg_match($preg, $value);
    }

    #验证数字
    /**
     * 验证是否是数字
     * @param $value为要验证的值
     * @return boolean
     */
    public static function check_number($value)
    {
        return is_numeric($value);
    }

    #验证两个值是否相同
    /**
     * 验证2个值是否相同
     * @param $value为要验证的值
     * @param $params = func_get_arg(1) $params[0] 为要比较的值
     * @return boolean
     */
    public static function check_eq($value)
    {
        $params   = func_get_arg(1);
        $eq_value = is_array($params) ? $params[0] : $params;
        if ($value == $eq_value) {
            return true;
        } else {
            return false;
        }
    }

    #验证值的范围
    /**
     * 验证值的范围
     * @param $value为要验证的值
     * @param $params = func_get_arg(1) $params[0] 最小值,$params[1] 最大值
     * @return boolean
     */
    public static function check_between($value)
    {
        $params = func_get_arg(1);
        if (!is_array($params)) {
            dump_file('check_between params error', 'validation_error.html');
        }
        $min = $params[0];
        $max = $params[1];
        if ($value < $min || $value > $max) {
            return false;
        } else {
            return true;
        }
    }

    #正则验证
    /**
     * 通过正则验证
     * @param $value为要验证的值
     * @param $params = func_get_arg(1) $params[0] 正则表达式
     * @return boolean
     */
    public static function check_preg($value)
    {
        $params = func_get_arg(1);
        $preg   = is_array($params) ? $params[0] : $params;
        return preg_match($preg, $value);
    }

    #验证ID
    /**
     * 验证是否合法id
     * @param $value为要验证的值
     * @return boolean
     */
    public static function check_id($value)
    {
        return preg_match('/^[1-9][0-9]*$/', $value);
    }

}

在模型中使用实例

<?php
namespace m;

use \lib\validation as V;

class sys_category extends V/*extends db*/
{

    /* 自动验证规则
     * 时机参数:both|add|update
     * //'must' => true, //$data数组必须存在此键名
     * //'notnull' => array('both','请输入0停用|1禁选|2正常!'), //此键值不能为空
     */
    protected $roles = array(
        'pid'    => array(
            'must'    => true,
            'notnull' => array('both', '请选择上级分类!'),
        ),
        'title'  => array(
            'notnull'    => array('both', '请输入分类名称!'),
            'notsibling' => array('both', '本级已存在此名称!'),

        ),
        'sort'   => array(
            'notnull' => array('both', '请输入排序数值!'),
        ),
        'status' => array(
            'notnull' => array('both', '请选择使用状态!'),
        ),
    );

    /**
     * 获取多条数据
     * @return array
     */
    public function getList()
    {
        $order = 'pid asc,sort desc';
        return $this->order($order)->select();
    } //获取多条数据

    /**
     * 获取多条数据
     * @return array
     */
    public function getTop()
    {
        $where        = array();
        $where['pid'] = 0;
        $order        = 'pid asc,sort desc';
        return $this->where($where)->order($order)->select();
    } //获取多条数据

    /**
     * 表单数据处理
     * @param  string $scene 模式 add|edit
     * @return mixed  数据操作后的返回值
     */
    public function processForm($scene = 'add')
    {
        //$_POST预处理
        $_POST['on_off'] = isset($_POST['on_off']) ? 1 : 0;

        //数据操作
        if ($scene == 'add') {
            return $this->add($_POST);
        } elseif ($scene == 'edit') {
            $where['id'] = ID('ID');
            return $this->where($where)->save($_POST);
        }
    } //表单数据处理

    /**
     * 获取一条数据
     * @return array
     */
    public function getInfo()
    {
        $where['id'] = ID();
        return $this->where($where)->find();
    } //获取一条数据

    /**
     * 验证是否同级中有相同名称
     * @param $value为要验证的值;
     * @return boolean
     */
    protected function check_notsibling($value)
    {
        if (!$this->valid_data) {
            parent::$dberror[] = '要验证的数据不存在';
            return false;
        }
        $bind[':pid']   = $this->valid_data['pid'];
        $bind[':title'] = $value;
        if ('update' == $this->valid_timing) {
            $bind[':id'] = $this->valid_data['ID'];

            $sql = 'SELECT * FROM ' . $this->table . ' WHERE `id`<>:id and `title`=:title and pid=:pid';
        } else {
            $sql = 'SELECT * FROM ' . $this->table . ' WHERE `title`=:title and pid=:pid';
        }
        $pre = self::db()->prepare($sql);
        $pre->execute($bind);
        if ($pre->fetch(\PDO::FETCH_ASSOC)) {
            return false;
        } else {
            return true;
        }
    } //验证同级中是否有相同名称

}

在模型文件中自定义验证方法说明

1. 验证方法命名必须以check_开头
2. 最多接受2个参数,$value为要验证的值。$params从$roles数组传递进来(如果有),多个值使用数组传递
3. 只能返回true或false
4. 可结合使用validation中的成员属性 $this->valid_timing,$this->valid_data,parent::$dberror[],$this->table
回帖