Подтвердить что ты не робот

Простейшая библиотека проверки подлинности форм для PHP?

Мне нужна простая php-библиотека, которая может использоваться для простого перехода к правилам и именам полей, и тогда проверка может быть легко выполнена. Также должен быть простой способ получить ошибки.

Любые предложения?

4b9b3361

Ответ 1

Я написал простой класс, свой собственный, объединив некоторые регулярные выражения, которые я собирал за эти годы с помощью функций санатизации и фильтрации PHP.

<?
/**
 * 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;
    }       



}

Теперь для этого требуется mootools для некоторого javascript, который вы видите здесь, но вы можете легко изменить его на свою любимую фреймворк 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('[email protected]', 'email');

Чтобы санатировать только один элемент:

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

Самое крутое в этом классе - это то, что вы можете отправить свою форму с помощью ajax или iframe target и выполнить полученный script. Не нужно обновлять страницу или повторно отправлять те же данные формы обратно в браузер:) Также, если требуется изменить script, нет сложной переопределенной структуры для анализа, просто измените ее так, как вы хотите:)

О да, не стесняйтесь использовать это где угодно. Нет лицензий

Ответ 2

Ответ от SchizoDuckie выше был потрясающим. Я использовал его код в проекте, над которым я работаю, с разрешения автора. Одна из проблем, которые я использовал с этим кодом, заключалась в том, что если обязательное поле не было отправлено, оно не зарегистрировало бы ошибку. Я изменил код, чтобы охватить этот сценарий. Я также удалил код для генерации HTML и javascript, так как мой проект требует разделения UI от логики на шаблон MVC. Измененный код просто возвращает результат, закодированный 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 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

Если вы хотите запрограммировать некоторые по своему усмотрению, у вас есть PHP 5.2.0 или выше. Затем вы можете просмотреть функции фильтра .

Ответ 5

Zend Forms, который можно использовать без всей рамки Zend

Ответ 6

Есть один, включенный в рамки Code Igniter, посмотрите здесь

Я рекомендую начать использовать одну из фреймворков PHP;)

Ответ 8

Этот класс проверки phpro.org выглядит очень хорошо для простой проверки данных:

http://www.phpro.org/classes/Validation-Class.html

Он поддерживает такие правила, как длина и т.д.