代码之家  ›  专栏  ›  技术社区  ›  Ali

最简单的PHP表单验证库?[关闭]

  •  33
  • Ali  · 技术社区  · 16 年前

    我需要一个简单的PHP库,它可以用来轻松地将规则和字段名传递给,然后可以轻松地执行验证。还应该有一种简单的方法来检索错误。

    有什么建议吗?

    8 回复  |  直到 6 年前
        1
  •  65
  •   SchizoDuckie    16 年前

    我自己编写了一个简单的类,将多年来收集的一些正则表达式与PHP的sanatize和filter函数结合在一起。

    <?
    /**
     * Pork Formvalidator. validates fields by regexes and can sanatize them. Uses PHP filter_var built-in functions and extra regexes 
     * @package pork
     */
    
    
    /**
     * Pork.FormValidator
     * Validates arrays or properties by setting up simple arrays
     * 
     * @package pork
     * @author SchizoDuckie
     * @copyright SchizoDuckie 2009
     * @version 1.0
     * @access public
     */
    class FormValidator
    {
        public static $regexes = Array(
                'date' => "^[0-9]{4}[-/][0-9]{1,2}[-/][0-9]{1,2}\$",
                'amount' => "^[-]?[0-9]+\$",
                'number' => "^[-]?[0-9,]+\$",
                'alfanum' => "^[0-9a-zA-Z ,.-_\\s\?\!]+\$",
                'not_empty' => "[a-z0-9A-Z]+",
                'words' => "^[A-Za-z]+[A-Za-z \\s]*\$",
                'phone' => "^[0-9]{10,11}\$",
                'zipcode' => "^[1-9][0-9]{3}[a-zA-Z]{2}\$",
                'plate' => "^([0-9a-zA-Z]{2}[-]){2}[0-9a-zA-Z]{2}\$",
                'price' => "^[0-9.,]*(([.,][-])|([.,][0-9]{2}))?\$",
                '2digitopt' => "^\d+(\,\d{2})?\$",
                '2digitforce' => "^\d+\,\d\d\$",
                'anything' => "^[\d\D]{1,}\$"
        );
        private $validations, $sanatations, $mandatories, $errors, $corrects, $fields;
    
    
        public function __construct($validations=array(), $mandatories = array(), $sanatations = array())
        {
            $this->validations = $validations;
            $this->sanatations = $sanatations;
            $this->mandatories = $mandatories;
            $this->errors = array();
            $this->corrects = array();
        }
    
        /**
         * Validates an array of items (if needed) and returns true or false
         *
         */
        public function validate($items)
        {
            $this->fields = $items;
            $havefailures = false;
            foreach($items as $key=>$val)
            {
                if((strlen($val) == 0 || array_search($key, $this->validations) === false) && array_search($key, $this->mandatories) === false) 
                {
                    $this->corrects[] = $key;
                    continue;
                }
                $result = self::validateItem($val, $this->validations[$key]);
                if($result === false) {
                    $havefailures = true;
                    $this->addError($key, $this->validations[$key]);
                }
                else
                {
                    $this->corrects[] = $key;
                }
            }
    
            return(!$havefailures);
        }
    
        /**
         *
         *  Adds unvalidated class to thos elements that are not validated. Removes them from classes that are.
         */
        public function getScript() {
            if(!empty($this->errors))
            {
                $errors = array();
                foreach($this->errors as $key=>$val) { $errors[] = "'INPUT[name={$key}]'"; }
    
                $output = '$$('.implode(',', $errors).').addClass("unvalidated");'; 
                $output .= "alert('there are errors in the form');"; // or your nice validation here
            }
            if(!empty($this->corrects))
            {
                $corrects = array();
                foreach($this->corrects as $key) { $corrects[] = "'INPUT[name={$key}]'"; }
                $output .= '$$('.implode(',', $corrects).').removeClass("unvalidated");';   
            }
            $output = "<script type='text/javascript'>{$output} </script>";
            return($output);
        }
    
    
        /**
         *
         * Sanatizes an array of items according to the $this->sanatations
         * sanatations will be standard of type string, but can also be specified.
         * For ease of use, this syntax is accepted:
         * $sanatations = array('fieldname', 'otherfieldname'=>'float');
         */
        public function sanatize($items)
        {
            foreach($items as $key=>$val)
            {
                if(array_search($key, $this->sanatations) === false && !array_key_exists($key, $this->sanatations)) continue;
                $items[$key] = self::sanatizeItem($val, $this->validations[$key]);
            }
            return($items);
        }
    
    
        /**
         *
         * Adds an error to the errors array.
         */ 
        private function addError($field, $type='string')
        {
            $this->errors[$field] = $type;
        }
    
        /**
         *
         * Sanatize a single var according to $type.
         * Allows for static calling to allow simple sanatization
         */
        public static function sanatizeItem($var, $type)
        {
            $flags = NULL;
            switch($type)
            {
                case 'url':
                    $filter = FILTER_SANITIZE_URL;
                break;
                case 'int':
                    $filter = FILTER_SANITIZE_NUMBER_INT;
                break;
                case 'float':
                    $filter = FILTER_SANITIZE_NUMBER_FLOAT;
                    $flags = FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND;
                break;
                case 'email':
                    $var = substr($var, 0, 254);
                    $filter = FILTER_SANITIZE_EMAIL;
                break;
                case 'string':
                default:
                    $filter = FILTER_SANITIZE_STRING;
                    $flags = FILTER_FLAG_NO_ENCODE_QUOTES;
                break;
    
            }
            $output = filter_var($var, $filter, $flags);        
            return($output);
        }
    
        /** 
         *
         * Validates a single var according to $type.
         * Allows for static calling to allow simple validation.
         *
         */
        public static function validateItem($var, $type)
        {
            if(array_key_exists($type, self::$regexes))
            {
                $returnval =  filter_var($var, FILTER_VALIDATE_REGEXP, array("options"=> array("regexp"=>'!'.self::$regexes[$type].'!i'))) !== false;
                return($returnval);
            }
            $filter = false;
            switch($type)
            {
                case 'email':
                    $var = substr($var, 0, 254);
                    $filter = FILTER_VALIDATE_EMAIL;    
                break;
                case 'int':
                    $filter = FILTER_VALIDATE_INT;
                break;
                case 'boolean':
                    $filter = FILTER_VALIDATE_BOOLEAN;
                break;
                case 'ip':
                    $filter = FILTER_VALIDATE_IP;
                break;
                case 'url':
                    $filter = FILTER_VALIDATE_URL;
                break;
            }
            return ($filter === false) ? false : filter_var($var, $filter) !== false ? true : false;
        }       
    
    
    
    }
    

    现在,对于您在这里看到的一些javascript,这需要使用mootools,但是您可以轻松地将其更改为您最喜欢的javascript框架。它所做的就是查找元素,并向其中添加“未验证”的CSS类。

    使用方法和我一直想要的一样简单:

    例子:

    $validations = array(
        'name' => 'anything',
        'email' => 'email',
        'alias' => 'anything',
        'pwd'=>'anything',
        'gsm' => 'phone',
        'birthdate' => 'date');
    $required = array('name', 'email', 'alias', 'pwd');
    $sanatize = array('alias');
    
    $validator = new FormValidator($validations, $required, $sanatize);
    
    if($validator->validate($_POST))
    {
        $_POST = $validator->sanatize($_POST);
        // now do your saving, $_POST has been sanatized.
        die($validator->getScript()."<script type='text/javascript'>alert('saved changes');</script>");
    }
    else
    {
        die($validator->getScript());
    }
    

    要仅验证一个元素:

    $validated = new FormValidator()->validate('blah@bla.', 'email');
    

    只需对一个元素进行消毒:

    $sanatized = new FormValidator()->sanatize('<b>blah</b>', 'string');
    

    这个类最酷的一点是,您可以用Ajax或iframe目标发送表单并执行生成的脚本。无需刷新页面或将相同的表单数据重新发送回浏览器:)此外,如果脚本需要更改,则不存在难以分析的过度设计的框架,只需以任何方式更改即可:)

    哦,是的,你想在哪儿都可以用。没有许可证

        2
  •  24
  •   John Pendlebury    13 年前

    上述精神分裂症患者的回答是令人敬畏的。我在作者许可的项目中使用了他的代码。我使用此代码时遇到的一个问题是,如果没有提交必需的字段,那么它就不会注册错误。我已经修改了代码来覆盖这个场景。我还删除了生成HTML和JavaScript的代码,因为我的项目要求按照MVC模式将UI与逻辑分离。修改后的代码只返回JSON编码的结果。我把修改后的代码放在这里,以防其他人使用。

    <?
    /**
    * Pork Formvalidator. validates fields by regexes and can sanatize them. Uses PHP       filter_var built-in functions and extra regexes 
    * @package pork
    */
    
    
    /**
    * Pork.FormValidator
    * Validates arrays or properties by setting up simple arrays
    * 
    * @package pork
    * @author SchizoDuckie
    * @copyright SchizoDuckie 2009
    * @version 1.0
    * @access public
    */
    class FormValidator
    {
        public static $regexes = Array(
                'date' => "^[0-9]{4}[-/][0-9]{1,2}[-/][0-9]{1,2}\$",
                'amount' => "^[-]?[0-9]+\$",
                'number' => "^[-]?[0-9,]+\$",
                'alfanum' => "^[0-9a-zA-Z ,.-_\\s\?\!]+\$",
                'not_empty' => "[a-z0-9A-Z]+",
                'words' => "^[A-Za-z]+[A-Za-z \\s]*\$",
                'phone' => "^[0-9]{10,11}\$",
                'zipcode' => "^[1-9][0-9]{3}[a-zA-Z]{2}\$",
                'plate' => "^([0-9a-zA-Z]{2}[-]){2}[0-9a-zA-Z]{2}\$",
                'price' => "^[0-9.,]*(([.,][-])|([.,][0-9]{2}))?\$",
                '2digitopt' => "^\d+(\,\d{2})?\$",
                '2digitforce' => "^\d+\,\d\d\$",
                'anything' => "^[\d\D]{1,}\$",
                'username' => "^[\w]{3,32}\$"
    );
    
    private $validations, $sanatations, $mandatories, $equal, $errors, $corrects, $fields;
    
    
    public function __construct($validations=array(), $mandatories = array(), $sanatations = array(), $equal=array())
    {
        $this->validations = $validations;
        $this->sanatations = $sanatations;
        $this->mandatories = $mandatories;
        $this->equal = $equal;
        $this->errors = array();
        $this->corrects = array();
    }
    
    /**
     * Validates an array of items (if needed) and returns true or false
     *
     * JP modofied this function so that it checks fields even if they are not submitted.
     * for example the original code did not check for a mandatory field if it was not submitted.
     * Also the types of non mandatory fields were not checked.
     */
    public function validate($items)
    {
        $this->fields = $items;
        $havefailures = false;
    
        //Check for mandatories
        foreach($this->mandatories as $key=>$val)
        {
            if(!array_key_exists($val,$items))
            {
                $havefailures = true;
                $this->addError($val);
            }
        }
    
        //Check for equal fields
        foreach($this->equal as $key=>$val)
        {
            //check that the equals field exists
            if(!array_key_exists($key,$items))
            {
                $havefailures = true;
                $this->addError($val);
            }
    
            //check that the field it's supposed to equal exists
            if(!array_key_exists($val,$items))
            {
                $havefailures = true;
                $this->addError($val);
            }
    
            //Check that the two fields are equal
            if($items[$key] != $items[$val])
            {
                $havefailures = true;
                $this->addError($key);
            }
        }
    
        foreach($this->validations as $key=>$val)
        {
                //An empty value or one that is not in the list of validations or one that is not in our list of mandatories
                if(!array_key_exists($key,$items)) 
                {
                        $this->addError($key, $val);
                        continue;
                }
    
                $result = self::validateItem($items[$key], $val);
    
                if($result === false) {
                        $havefailures = true;
                        $this->addError($key, $val);
                }
                else
                {
                        $this->corrects[] = $key;
                }
        }
    
        return(!$havefailures);
    }
    
    /* JP
     * Returns a JSON encoded array containing the names of fields with errors and those without.
     */
    public function getJSON() {
    
        $errors = array();
    
        $correct = array();
    
        if(!empty($this->errors))
        {            
            foreach($this->errors as $key=>$val) { $errors[$key] = $val; }            
        }
    
        if(!empty($this->corrects))
        {
            foreach($this->corrects as $key=>$val) { $correct[$key] = $val; }                
        }
    
        $output = array('errors' => $errors, 'correct' => $correct);
    
        return json_encode($output);
    }
    
    
    
    /**
     *
     * Sanatizes an array of items according to the $this->sanatations
     * sanatations will be standard of type string, but can also be specified.
     * For ease of use, this syntax is accepted:
     * $sanatations = array('fieldname', 'otherfieldname'=>'float');
     */
    public function sanatize($items)
    {
        foreach($items as $key=>$val)
        {
                if(array_search($key, $this->sanatations) === false && !array_key_exists($key, $this->sanatations)) continue;
                $items[$key] = self::sanatizeItem($val, $this->validations[$key]);
        }
        return($items);
    }
    
    
    /**
     *
     * Adds an error to the errors array.
     */ 
    private function addError($field, $type='string')
    {
        $this->errors[$field] = $type;
    }
    
    /**
     *
     * Sanatize a single var according to $type.
     * Allows for static calling to allow simple sanatization
     */
    public static function sanatizeItem($var, $type)
    {
        $flags = NULL;
        switch($type)
        {
                case 'url':
                        $filter = FILTER_SANITIZE_URL;
                break;
                case 'int':
                        $filter = FILTER_SANITIZE_NUMBER_INT;
                break;
                case 'float':
                        $filter = FILTER_SANITIZE_NUMBER_FLOAT;
                        $flags = FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND;
                break;
                case 'email':
                        $var = substr($var, 0, 254);
                        $filter = FILTER_SANITIZE_EMAIL;
                break;
                case 'string':
                default:
                        $filter = FILTER_SANITIZE_STRING;
                        $flags = FILTER_FLAG_NO_ENCODE_QUOTES;
                break;
    
        }
        $output = filter_var($var, $filter, $flags);            
        return($output);
    }
    
    /** 
     *
     * Validates a single var according to $type.
     * Allows for static calling to allow simple validation.
     *
     */
    public static function validateItem($var, $type)
    {
        if(array_key_exists($type, self::$regexes))
        {
                $returnval =  filter_var($var, FILTER_VALIDATE_REGEXP, array("options"=> array("regexp"=>'!'.self::$regexes[$type].'!i'))) !== false;
                return($returnval);
        }
        $filter = false;
        switch($type)
        {
                case 'email':
                        $var = substr($var, 0, 254);
                        $filter = FILTER_VALIDATE_EMAIL;        
                break;
                case 'int':
                        $filter = FILTER_VALIDATE_INT;
                break;
                case 'boolean':
                        $filter = FILTER_VALIDATE_BOOLEAN;
                break;
                case 'ip':
                        $filter = FILTER_VALIDATE_IP;
                break;
                case 'url':
                        $filter = FILTER_VALIDATE_URL;
                break;
        }
        return ($filter === false) ? false : filter_var($var, $filter) !== false ? true :     false;
    }           
    }
    ?>
    
        3
  •  12
  •   Ólafur Waage    16 年前

    如果您想自己编写一些程序,并且您有php 5.2.0或更高版本。然后你可以查看 filter functions.

        4
  •  8
  •   David d C e Freitas    14 年前
        5
  •  5
  •   Hamman Samuel Priyank Bolia    6 年前

    Zend Forms 它可以在没有整个Zend框架的情况下使用

        6
  •  4
  •   Hamman Samuel Priyank Bolia    6 年前

    代码点火器框架中有一个,请看一下 here

    我建议开始使用其中一个PHP框架;)

        7
  •  2
  •   Rémy    16 年前

    symfony框架的一部分名为 交汇形态 它可以独立于整个框架使用。

    看一看 the framework documentation .

        8
  •  1
  •   Hamman Samuel Priyank Bolia    6 年前

    这个phpro.org验证类看起来非常适合进行简单的数据验证:

    https://phpro.org/classes/Validation-Class.html

    它支持长度等规则。