Форма валидатор класса и занятия ребенка


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

В принципе, есть форма абстрактного класса (lev_form), которые вы хотели выразить. В расширенных классов, вы хотели написать метод__Construct метод, который создает все поля формы и поля формы проверки. Вы могли бы затем создать экземпляр этого класса, и запустить его validate_form() метод, чтобы проверить $_POST, где и $_FILES больше данных от всех ребенка поля формы, и своего ребенка форма проверки полей.

Это в некоторой степени имитирует то, как в jQuery валидация формы работает, а окончательный план должен дать классу возможность распечатать класс валидации jQuery для формы, на основе тех же данных, что серверная часть использует проверку.

Вот это класс формы:

<?php

    abstract class lev_form {

        protected $fields = array();

        abstract public function __construct() {
            // set up form fields and field vlaidations here

        }

        protected function create_field($name, $label) {
            lev::load_library('lev_forms/lev_field');
            $this->fields[] = new lev_field($name, $label);
        }

        // validates POST and FILES data
        public function validate_form() {
            try {
                foreach($this->fields as $field_object) {
                    $field_object->validate_field();
                }
            } catch (Exception $e) {
                return $e->getMessage();
            }
            return true;
        }

        // validates form using jQuery
        public function print_jquery_validator($selector) {

        }
    }
?>

Здесь есть класс для поля формы:

<?php

    class lev_field {

        protected $name;
        protected $label;
        protected $validations = array();

        public function __construct($name, $label) {
            $this->name = $name;
            $this->label = $label;
        }

        public function create_validation($type, $argument = null, $message = null) {
            lev::load_library('lev_forms/lev_field_validation');
            $this->validations[] = new lev_field_validation($type, $argument, $message, $this->name, $this->label);
        }

        public function validate_field() {
            foreach ($this->validation as $validation_object) {
                $validation_object->validate();
            }
        }
    }
?>

А вот форма полей классов проверка:

<?php

    class lev_field_validation {

        protected $type;
        protected $argument;
        protected $message;
        protected $field_name;

        protected static $default_validation_error_messages = array(
            'required' => '[field_label] is a required field.',
            'minlength' => '[field_label] must be at least [validation_argument] characters in length.',
            'maxlength' => '[field_label] must be at most [validation_argument] characters in length.',
            'min' => '[field_label] must be at least [validation_argument].',
            'max' => '[field_label] must be at most [validation_argument].',
            'email' => '[field_label] must be a valid email address.',
            'url' => '[field_label] must be a valid URL.',
            'date' => '[field_label] must be a valid date.',
            'number' => '[field_label] must be a numeric value.',
            'digits' => '[field_label] must only contain digits.',
            'boolean' => '[field_label] must be true or false.',
            'equalto' => '[field_label] must be equal to [validation_argument].',
            'file_accept_extensions' => '[field_label] must be a valid file type.',
            'file_max_size' => '[field_label] must have a file size no greater than [validation_argument] bytes.'
        );

        public function __construct($type, $argument, $message, $field_name, $field_label) {
            $this->type = $type;
            $this->argument = $argument;
            $this->field_name = $field_name;
            if ($message) {
                $this->message = $message;
            } else if (array_key_exists($type, self::$default_validation_error_messages)) {
                $this->message = preg_replace(array('\[field_label\]', '\[validation_argument\]'), array($field_label, $argument), self::$default_validation_error_messages[$type]);
            } else {
                trigger_error('No set error message or default error message for form validation "' . $type . '"', E_USER_ERROR);
            }
        }

        public function validate() {
            $this->error_check_validation();
            $this->check_validation();
        }

        protected function error_check_validation() {
            if (array_search($this->field_name, $_POST) === true) {
                if ($this->type == 'file_accept_extensions' || $this->type == 'file_max_size') trigger_error('Use of invalid form validation "' . $this->type . '" on non-file field.', E_USER_ERROR);
            } else if (array_search($this->field_name, $_FILES) === true) {
                if ($this->type != 'file_accept_extensions' && $this->type != 'file_max_size') trigger_error('Use of invalid form validation "' . $this->type . '" on file field. You may only use this validation on non-file fields.', E_USER_ERROR);
            } else {
                trigger_error('Form field "' . $this->field_name . '" not found in $_POST or $_FILES array even though it exists in this form\'s class.', E_USER_ERROR);
            }
        }

        protected function check_validation() {
            switch ($validation->type) {
                case 'required':
                    if (!$this->required()) throw new Exception($this->message);
                    break;
                case 'callback':
                    if ($_POST[$this->field_name] !== '' && $this->argument($_POST[$this->field_name])) throw new Exception($this->message);
                    break;
                case 'minlength':
                    if ($_POST[$this->field_name] !== '' && strlen($_POST[$this->field_name]) < $this->argument) throw new Exception($this->message);
                    break;
                case 'maxlength':
                    if ($_POST[$this->field_name] !== '' && strlen($_POST[$this->field_name]) > $this->argument) throw new Exception($this->message);
                    break;
                case 'min':
                    if ($_POST[$this->field_name] !== '' && $_POST[$this->field_name] > $this->argument) throw new Exception($this->message);
                    break;
                case 'max':
                    if ($_POST[$this->field_name] !== '' && $_POST[$this->field_name] < $this->argument) throw new Exception($this->message);
                    break;
                case 'email':
                    if ($_POST[$this->field_name] !== '' && !filter_var($_POST[$this->field_name], FILTER_VALIDATE_EMAIL)) throw new Exception($this->message);
                    break;
                case 'url':
                    if ($_POST[$this->field_name] !== '' && !filter_var($_POST[$this->field_name], FILTER_VALIDATE_URL)) throw new Exception($this->message);
                    break;
                case 'date':
                    if ($_POST[$this->field_name] !== '' && !strtotime($_POST[$this->field_name])) throw new Exception($this->message);
                    break;
                case 'number':
                    if ($_POST[$this->field_name] !== '' && !is_numeric($_POST[$this->field_name])) throw new Exception($this->message);
                    break;
                case 'digits':
                    if ($_POST[$this->field_name] !== '' && !is_int($_POST[$this->field_name]) && $_POST[$this->field_name] >= 0) throw new Exception($this->message);
                    break;
                case 'boolean':
                    if ($_POST[$this->field_name] !== '' && !filter_var($_POST[$this->field_name], FILTER_VALIDATE_BOOLEAN)) throw new Exception($this->message);
                    break;
                case 'equalto':
                    if ($_POST[$this->field_name] !== '' && $_POST[$this->field_name] !== $_POST[$this->argument]) throw new Exception($this->message);
                    break;
                case 'file_accept_extensions':
                    $extension = preg_replace('/.+?\.(.+)$/', '$1', $_FILES[$this->field_name]['name']);
                    if (array_search($extension, $this->argument) === false) throw new Exception($this->message);
                    break;
                case 'file_max_size':
                    if (filesize($_FILES[$this->field_name]['tmp_name']) > $this->argument) throw new Exception($this->message);
                    break;
                default:
                    trigger_error('Validation "' . $this->type . '" does not exist. This validation was called by field "' . $this->field_name . '".', E_USER_ERROR);
            }
            return false;
        }

        protected function required() {
            if ($this->argument && !$_POST[$this->argument]) return true;
            return ($_POST[$this->field_name] === '') ? false : true;
        }
    }
?>


479
2
задан 29 марта 2011 в 10:03 Источник Поделиться
Комментарии
2 ответа

Я прыгнул прямо к lev_field_validation как это самый интересный класс.


  1. Всякий раз, когда я вижу гигантский переключатель() блок, я сразу подозреваю, что есть много подклассов, пытаясь вырваться. Каждая проверка должна быть другой подкласс с соответствующим изменением check_validation()error_check_validation() в паре случаев).

  2. Вы повторяете $_POST, где[$этом->имя_поля] !== " двенадцать раз-верный признак того, что это должно быть воплощен в свой собственный метод. Для одна вещь, вы должны проверить, если поле существует с помощью array_key_exists() прежде чем схватить его значение.

  3. Идиома $х ? ложь : правда можно заменить !$х. Во второй строке требуется() таким образом будет возвращать $_POST, где[$этом->имя_поля] !== ";.

  4. Добавить некоторые комментарии, объясняющие, что происходит в целом. Например, дано его имя я ожидаю, что требуется() скажите мне, если значение является обязательным, однако он, как представляется, означает, что значение был принят и должен быть проверен. Разве "> 5" проверка выполнена, если я не указать значение? Если нет, то объясните, почему или по крайней мере указать на это.

2
ответ дан 30 марта 2011 в 01:03 Источник Поделиться


  • Отсутствие замечаний, безусловно, вызывает беспокойство.

  • Код в случае заявления относительно нечитаемым, и содержит большое количество дублирования. Думать о том, как переписать это не так много дублирующегося кода. Предыдущий ответ предполагает наследование, я бы предложил избегать полностью ОО.

  • Тот факт, что вы решили использовать ОО это заметно добавляя много довольно бессмысленных наворотов в свой реальный код. Попробуйте реализовать то же самое без ОО и сравнивая результаты в личных упражнений.

  • Архитектурная беспокойство: что, если пользователь хочет выполнить пользовательскую проверку?

  • Ваш код не является интернационализация курсе. В то время как приятно видеть, что у вас есть отдельная структура для большинства сообщений, которые вы написали, в triggererror() строк содержат ориентированные на пользователя строки прямо в коде, который мешает спокойно интернационализации.

1
ответ дан 12 апреля 2011 в 02:04 Источник Поделиться