zoukankan      html  css  js  c++  java
  • Codeigniter-验证数据类

    个人需求,仿着CI的表单验证写了一个自己的验证类

    1.定义验证类

    <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    // required    No    如果元素为空,则返回FALSE     
    // matches    Yes    如果表单元素的值与参数中对应的表单字段的值不相等,则返回FALSE    matches[form_item]
    // is_unique    Yes    如果表单元素的值与指定数据表栏位有重复,则返回False(译者注:比如is_unique[User.Email],那么验证类会去查找User表中Email栏位有没有与表单元素一样的值,如存重复,则返回false,这样开发者就不必另写Callback验证代码。)    is_unique[table.field]
    // min_length    Yes    如果表单元素值的字符长度少于参数中定义的数字,则返回FALSE    min_length[6]
    // max_length    Yes    如果表单元素值的字符长度大于参数中定义的数字,则返回FALSE    max_length[12]
    // exact_length    Yes    如果表单元素值的字符长度与参数中定义的数字不符,则返回FALSE    exact_length[8]
    // greater_than    Yes    如果表单元素值是非数字类型,或小于参数定义的值,则返回FALSE    greater_than[8]
    // less_than    Yes    如果表单元素值是非数字类型,或大于参数定义的值,则返回FALSE    less_than[8]
    // alpha    No    如果表单元素值中包含除字母以外的其他字符,则返回FALSE     
    // alpha_numeric    No    如果表单元素值中包含除字母和数字以外的其他字符,则返回FALSE     
    // alpha_dash    No    如果表单元素值中包含除字母/数字/下划线/破折号以外的其他字符,则返回FALSE     
    // numeric    No    如果表单元素值中包含除数字以外的字符,则返回 FALSE     
    // integer    No    如果表单元素中包含除整数以外的字符,则返回FALSE     
    // decimal    No    如果表单元素中包含非十进制数字时,则返回FALSE     
    // is_natural    No    如果表单元素值中包含了非自然数的其他数值 (其他数值不包括零),则返回FALSE。自然数形如:0,1,2,3....等等。     
    // is_natural_no_zero    No    如果表单元素值包含了非自然数的其他数值 (其他数值包括零),则返回FALSE。非零的自然数:1,2,3.....等等。     
    // valid_email    No    如果表单元素值包含不合法的email地址,则返回FALSE     
    // valid_emails    No    如果表单元素值中任何一个值包含不合法的email地址(地址之间用英文逗号分割),则返回FALSE。     
    // valid_ip    No    如果表单元素的值不是一个合法的IP地址,则返回FALSE。通过可选参数"IPv4"或"IPv6"来指定 IP 地址格式。     
    // valid_base64    No    如果表单元素的值包含除了base64 编码字符之外的其他字符,则返回FALSE。
    
    class Validation {
    
        protected $_field_data = array();
        protected $_config_rules = array();
    
        public function __construct()
        {
            //获取CI对象
            $this->CI =& get_instance();
    
            //读取验证类配置文件 TODO
            
        }
    
    
        public function set_rules($field, $rules = '')
        {
            //如果field是数组,我们遍历它并递归调用这些验证方法
            if (is_array($field)) {
                foreach ($field as $key => $row) {
                    //检查数组数据
                    if (!isset($row['field']) OR !isset($row['rules'])){
                        continue;
                    }
    
                    $this->set_rules($row['field'], $row['rules']);
                }
                return $this;
            }
    
            //不存在$field或者为空,返回
            if (!is_string($field) OR $field == '') {
                return $this;
            }
    
            //如果field是数组,拆分
            if (strpos($field, '[') !== FALSE AND preg_match_all('/[(.*?)]/', $field, $matches)) {
    
                foreach ($matches[1] as $index) {
                    if ($index != ''){
                        $indexes[] = $index;
                    }
                }
    
                $is_array = TRUE;
            }
            else {
                $indexes = array();
                $is_array = FALSE;
            }
    
            //设置字段规则
            $this->_field_data[$field] = array(
                'field' => $field,
                'rules' => $rules,
                'is_array' => $is_array,
                'keys' => $indexes,
                'data' => NULL,
            );
    
            return $this;
        }
    
        public function _reduce_array($array, $keys, $i = 0)
        {
            if(is_array($array)) {
                //递归查询每个键名下的数组
                if (isset($keys[$i])){
                    if (isset($array[$key[$i]])) {
                        $array = $this->_reduce_array($array[$key[$i]], $keys, ($i+1));
                    }
                    else{
                        return NULL;
                    }
                }
                else {
                    return $array;
                }
            }
    
            return $array;
        }
    
        public function _execute($row, $cycles = 0)
        {
            $is_valid = TRUE;
            //如果字段数据data是数组,我们执行递归调用
            if (is_array($row['data'])) {
                foreach ($data as $key => $value) {
                    if ( ! $this->_execute($row, $cycles)) {
                        $is_valid = FALSE;
                        break;
                    }
    
                    $cycles++;
                }
    
                return $is_valid;
            }
            extract($row);
            // --------------------------------------------------------------------
    
            //如果字段为空,并不要求,没必要进行验证
            $callback = FALSE;
            if (!in_array('required', $rules) AND is_null($data)){
                return $is_valid;
            }
    
            // --------------------------------------------------------------------
    
            //应用到复选框TODO
            
            // --------------------------------------------------------------------
            
            //遍历并执行验证
            foreach ($rules as $key => $rule) {
    
                //如果验证规则带有回调函数
                $callback = FALSE;
                if (substr($rule, 0, 9) == 'callback_'){
                    $rule = substr($rule, 9);
                    $callback = TRUE;
                }
    
                //如果验证规则带有参数
                $param = FALSE;
                if (preg_match("/(.*?)[(.*)]/", $rule, $match)){
                    $rule = $match[1];
                    $param= $match[2];
                }
    
                // 调用对应规则的方法验证
                // 回调函数验证
                if ($callback === TRUE) {
    
                    if (!method_exists($this->CI, $rule)){
                        continue;
                    }
    
                    $is_valid = $this->CI->$rule($data, $param);
    
                    //如果不要求并验证结果为真,不进行其他规则的验证
                    if ( ! in_array('required', $rules, TRUE) AND $is_valid !== FALSE)
                    {
                        continue;
                    }                
                }
                else{
                    //如果验证类中不包含该验证方法,尝试php内置方法
                    if (!method_exists($this, $rule)) {
    
                        if (function_exists($rule)) {
                            $is_valid = $rule($data);
                        }
                        else {
                            log_message('error', "找不到对应的验证方法:".$rule);
                        }
    
                        continue;
                    }
                    
                    $is_valid = $this->$rule($data, $param);            
                }
    
                //如果验证不通过,记录错误
                if ($is_valid === FALSE) {
                    if (isset($this->_error_messages[$rule])) {
                        log_message('error', $field.$cycles.'验证'.$rule.'不通过');
                    }
                    return $is_valid;
                }
    
            }
    
            return TRUE;
        }
    
        public function run($data)
        {
            //如果没有设置验证规则
            if (count($this->_field_data) == 0) {
                //检查是否设置默认验证规则配置文件
                //TODO
            }
    
            foreach ($this->_field_data as $field => $row) {
    
                //根据field的名字是数组或者字符串,决定我们从哪里获取它的值
                if ($row['is_array'] == TRUE) {
                    $row['data'] = $this->_reduce_array($data, $row['keys']);//获取多维数组的值
                }
                else {
                    if (isset($data[$field]) AND $data[$field] != ''){
                        $row['data'] = $data[$field];
                    }
                }
    
                //执行验证
                if (!$this->_execute($row)){
                    return FALSE;
                }
            }
    
            return TRUE;
        }
    
        public function required($str)
        {
            log_message('error',$str);
            if (!is_array($str)) {
                return (trim($str) == '') ? FALSE : TRUE;
            }
            else {
                return (!empty($str));
            }
        }
    
        /**
         * Performs a Regular Expression match test.
         *
         * @access    public
         * @param    string
         * @param    regex
         * @return    bool
         */
        public function regex_match($str, $regex)
        {
            if ( ! preg_match($regex, $str))
            {
                return FALSE;
            }
    
            return  TRUE;
        }
        
        // --------------------------------------------------------------------
    
        /**
         * Match one field to another
         *
         * @access    public
         * @param    string
         * @param    field
         * @return    bool
         */
        public function is_unique($str, $field)
        {
            list($table, $field)=explode('.', $field);
            $query = $this->CI->db->limit(1)->get_where($table, array($field => $str));
            
            return $query->num_rows() === 0;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Minimum Length
         *
         * @access    public
         * @param    string
         * @param    value
         * @return    bool
         */
        public function min_length($str, $val)
        {
            if (preg_match("/[^0-9]/", $val))
            {
                return FALSE;
            }
    
            if (function_exists('mb_strlen'))
            {
                return (mb_strlen($str) < $val) ? FALSE : TRUE;
            }
    
            return (strlen($str) < $val) ? FALSE : TRUE;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Max Length
         *
         * @access    public
         * @param    string
         * @param    value
         * @return    bool
         */
        public function max_length($str, $val)
        {
            if (preg_match("/[^0-9]/", $val))
            {
                return FALSE;
            }
    
            if (function_exists('mb_strlen'))
            {
                return (mb_strlen($str) > $val) ? FALSE : TRUE;
            }
    
            return (strlen($str) > $val) ? FALSE : TRUE;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Exact Length
         *
         * @access    public
         * @param    string
         * @param    value
         * @return    bool
         */
        public function exact_length($str, $val)
        {
            if (preg_match("/[^0-9]/", $val))
            {
                return FALSE;
            }
    
            if (function_exists('mb_strlen'))
            {
                return (mb_strlen($str) != $val) ? FALSE : TRUE;
            }
    
            return (strlen($str) != $val) ? FALSE : TRUE;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Valid Email
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function valid_email($str)
        {
            return ( ! preg_match("/^([a-z0-9+_-]+)(.[a-z0-9+_-]+)*@([a-z0-9-]+.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Valid Emails
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function valid_emails($str)
        {
            if (strpos($str, ',') === FALSE)
            {
                return $this->valid_email(trim($str));
            }
    
            foreach (explode(',', $str) as $email)
            {
                if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)
                {
                    return FALSE;
                }
            }
    
            return TRUE;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Validate IP Address
         *
         * @access    public
         * @param    string
         * @param    string "ipv4" or "ipv6" to validate a specific ip format
         * @return    string
         */
        public function valid_ip($ip, $which = '')
        {
            return $this->CI->input->valid_ip($ip, $which);
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Alpha
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function alpha($str)
        {
            return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Alpha-numeric
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function alpha_numeric($str)
        {
            return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Alpha-numeric with underscores and dashes
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function alpha_dash($str)
        {
            return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Numeric
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function numeric($str)
        {
            return (bool)preg_match( '/^[-+]?[0-9]*.?[0-9]+$/', $str);
    
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Is Numeric
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function is_numeric($str)
        {
            return ( ! is_numeric($str)) ? FALSE : TRUE;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Integer
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function integer($str)
        {
            return (bool) preg_match('/^[-+]?[0-9]+$/', $str);
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Decimal number
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function decimal($str)
        {
            return (bool) preg_match('/^[-+]?[0-9]+.[0-9]+$/', $str);
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Greather than
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function greater_than($str, $min)
        {
            if ( ! is_numeric($str))
            {
                return FALSE;
            }
            return $str > $min;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Less than
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function less_than($str, $max)
        {
            if ( ! is_numeric($str))
            {
                return FALSE;
            }
            return $str < $max;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Is a Natural number  (0,1,2,3, etc.)
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function is_natural($str)
        {
            return (bool) preg_match( '/^[0-9]+$/', $str);
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Is a Natural number, but not a zero  (1,2,3, etc.)
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function is_natural_no_zero($str)
        {
            if ( ! preg_match( '/^[0-9]+$/', $str))
            {
                return FALSE;
            }
    
            if ($str == 0)
            {
                return FALSE;
            }
    
            return TRUE;
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Valid Base64
         *
         * Tests a string for characters outside of the Base64 alphabet
         * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045
         *
         * @access    public
         * @param    string
         * @return    bool
         */
        public function valid_base64($str)
        {
            return (bool) ! preg_match('/[^a-zA-Z0-9/+=]/', $str);
        }
    }

    因为我只支持前台能运行js的用户,只是防止非法人跨过浏览器直接访问

    所以,我的验证类阉割了原来显示验证错误的功能,一旦有一个验证不通过,记录日志并直接退出!简单粗暴 哈哈

    另外,该类还有没有完善的地方,复选框部分代码,和读取配置文件设置默认验证规则的代码,回调函数只能限制在控制器的问题,待完善

    2.加入自动加载中

    3.配置使用 在控制器中加入如下代码,

    //验证$input
    $rules = array(
        array('field' => 'name','rules' => array('required', 'callback_test'))
    );
    if (!$this->validation->set_rules($rules)->run($input)){
        exit('请检查是否javascript不生效了!');
    }
  • 相关阅读:
    Objective-C中#define的常见用法
    OpenGL ES为缓存提供数据的7个步骤
    绕指定点旋转算法
    矩阵平移旋转缩放公式
    矩阵和向量的乘法顺序
    干货集合
    RGB颜色空间与YCbCr颜色空间的互转
    UINavi中push控制器的时候隐藏TabBar
    CZLayer的阴影
    CALayer初认识
  • 原文地址:https://www.cnblogs.com/jdhu/p/4234468.html
Copyright © 2011-2022 走看看