оптимизация php валидатора до ООП - PullRequest
1 голос
/ 30 января 2012

Мне нужен класс валидатора php, который проверяет вводимые пользователем данные.

Я хочу, чтобы он мог принимать соответствующий массив полей => значений типа:

array(
    "username" => "Alex",
    "email_address" => "@@#3423£alex@my.mail.com"
);

и затем возвращатьмассив ошибок вроде этого:

array(
    "username" => "",
    "email_address" => "Invalid Email Address"
);

Но я действительно борюсь за то, КАК, черт возьми, я собираюсь это сделать!

Я прочитал бесчисленные страницы о валидаторах PHP ипрочитайте, что лучший способ сделать это с помощью шаблона стратегии.Но я не знаю, как ??

Как ... Это то, что у меня так далеко:

class Validator {

private
$_errors,
$_fields,

static private $_map = array (
    "firstname" => "name",
    "surname" => "name",
    "agency_name" => "name",
    "agency_office" => "name",
    "username" => "username",
    "email_address" => "email_address",
);
public function __construct( array $fields ) {
    $this->_fields = $fields;
}
public function validate() {
    foreach ( $this->_fields as $field => $value ) {
        if ( method_exists( __CLASS__, self::$_map[$field] ) ) {
            if ( in_array( $field, self::$_map ) ) {
                $this->{self::$_map[$field]}( $field, $value );
            }
        }
        else {
            die( " Unable to validate field $field" );
        }
    }
}
public function get_errors() {
    return $this->_errors;
}
private function name( $field, $value ) {
    if ( !preg_match( "/^[a-zA-Z]{2,50}$/", $value ) ) {
        $this->errors[$field] = "Invalid. Must be 2 to 50 alphanumerical characters";
    }
}
private function username( $field, $value ) {
    if ( !preg_match( "/^[a-zA-Z0-9_\-]{10,50}$/", $value ) ) {
        $this->errors[$field] = "Invalid. Must be 10 to 50 characters. Can contain digits, characters, _ (underscore) and - (hyphen)";
    }
}
private function password( $field, $value ) {
    if ( !preg_match( "/^[a-zA-Z0-9\.\-]{8,30}$/", $value ) ) {
        $this->_errors[$field] = "Invalid. Must be 8 to 30 characters. Can contain digits, characters, . (full stop) and - (hyphen)";
    }
}
private function email_address( $field, $value ) {
    if ( !filter_var( $value, FILTER_VALIDATE_EMAIL ) ) {
        $this->_errors[$field] = "Invalid Email Address";
    }
}
}

Проблемы с этим, он даже не рассматривает соединения с базой данныхнапример, уже зарегистрированные имена пользователей,

Кроме того, пароли не совпадают

Я только что получил блок кодировщиков, и он разрушает меня изнутри: (

Кто-нибудь может дать объяснение необходимых классов и функций, которые должен выполнять каждый класс?

Мне действительно нужны входные и выходные данные в формате, который уже объяснен!

Спасибо, оченьМного интернет-людей!

1 Ответ

1 голос
/ 30 января 2012

В составе моего MVC я решил ту же проблему. Я мог бы дать вам список, но в нескольких строках попытаться описать как.

Я получил 3 базовых класса Form, Validator, Field, каждый из объектов этого класса настраивается через один файл YAML, структурированный примерно так:

name: // field name
  i18n:             [ ru, en ] // is the field i18n
  field:
    class:          Base // class to use for field
    options:        { specific_save: true } // options from available (defined in class)
    attributes:     { } // attributes, for HTML rendering
  validator:
    class:          String // Class to validate with
    options:        { required: true, max: 100 } // options for validator

Итак, давайте начнем с Form, когда объект конструирует форму, принимает файл YAML, описанный выше, и в связи с этим конфигурация создает поля. Примерно так:

// Imlement this function to configure form;
foreach ($this->_config as $f => $c)
{
    $class = '\\Lighty\\Form\\Field\\' . (isset($c['field']['class']) && $c['field']['class'] ? $c['field']['class'] : 'Base');
    $o = isset($c['field']['options']) && is_array($c['field']['options']) ? $c['field']['options'] : array();
    $a = isset($c['field']['attributes']) && is_array($c['field']['attributes']) ? $c['field']['attributes'] : array();
    $field = new $class($this, $o, $a);
    $field->setName($f);

    $class = '\\Lighty\\Form\\Validator\\' . (isset($c['validator']['class']) && $c['validator']['class'] ? $c['validator']['class'] : 'Base');
    $o = isset($c['validator']['options']) && is_array($c['validator']['options']) ? $c['validator']['options'] : array();
    $m = isset($c['validator']['messages']) && is_array($c['validator']['messages']) ? $c['validator']['messages'] : array();
    $field->setValidator($validator = new $class($field, $o, $m));

    if (isset($this->_options['default'][$f]))
    {
        $field->setValue($this->_options['default'][$f]);
    }

    if (isset($c['i18n']))
    {
        if (is_array($c['i18n']))
        {
            $field->setCultures($c['i18n']);
        }
        $field->setI18n((bool) $c['i18n']);
    }

    $this->addField($field);

Итак, теперь у нас есть форма с полями и валидатором для каждого поля, затем для проверки я использую этот механизм:

Форма проходит через каждое поле, вызывая метод validate(), Поле (получившее связанное значение) вызывает validate($value) метод связанного валидатора, передавая сохраненное значение. Внутри этого метода Validator вызывает метод validateOption(), в котором есть простой переключатель для каждой опции, например:

switch ($o)
{
    case 'required':
        $valid = $state && trim($value) != '' || !$state;
        break;
    default:
        return \warning(sprintf('Undefined validator option "%s" in %s validator class', $o, get_class($this->getField()->getValidator())), null);
}

Здесь вы можете увидеть подтверждение по необходимой опции. Если мне нужно больше валидаторов, я расширяю класс Базового валидатора, определяю еще несколько опций и переопределяю validateOption(), где в default операторе опции switch ставится parent::validateOption(). Указанные параметры проверяются в новом классе, а старый - в базовом классе валидатора.

Если есть вопросы ... Пожалуйста.

...