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不生效了!');

}

你可能感兴趣的:(CodeIgniter)