С одной стороны, валидация формы может рассматриваться как часть логики приложения и, следовательно, принадлежность к модели.
С другой стороны, он напрямую касается ввода, поступающего из представления, и обрабатывает ошибки отображения и т. Д. С этого угла имеет смысл добавить его в контроллеры.
Какой из них правильный подход с точки зрения MVC?
PS Моя форма проверки фактически состоит только в написании списка полей, их правил и передаче его в библиотеку проверки формы, которая возвращает true / false о том, прошла ли она проверку или нет.
Пример:
$this->load->library('form_validation'); $this->form_validation->set_rules('name', 'Name', 'required'); $this->form_validation->set_rules('email', 'Email', 'required|valid_email'); //........ if ($this->form_validation->validate()) // Process data else $this->register_form(); //A controller action that will show a view with errors
Должно ли это быть поставлено в контроллер или модель?
Валидация – это проблема модели. Только модель знает, как выглядят ваши данные. Вы описываете свои поля данных в модели, поэтому вы должны описывать правила проверки для этих полей в одном и том же месте.
Мне кажется очевидным, но я с удовольствием прислушиваюсь к противникам.
В идеале вы хотите получить 3 уровня проверки:
Я бы сказал, что код проверки формы должен быть в контроллере (а не в модели) в большинстве случаев.
Madmartigan лучше всего упомянул в своем комментарии выше «Проверка формы! == Проверка данных. Не все формы взаимодействуют с моделью»
Веб-формы логически являются частью части View / Controller MVC, поскольку пользователь взаимодействует с ними в представлении.
Кажется, что каждый всегда говорит, что модель справляется с этим вопросом, который имеет свои достоинства (по сравнению с противоположным), но я думаю, что ответ на этот вопрос более утончен. Валидация самих данных должна выполняться на модели.
Но есть и другие типы проверки , например, была ли форма отправлена с непредвиденными полями (в целях безопасности, очевидно), или есть ли у пользователя разрешение на выполнение запрошенной операции. Помещая эти типы валидации в модель, она цементирует модель (абстракцию данных), чтобы полностью разделить вещи, например, как работает пользовательская система или как представления формы оцениваются для целей безопасности.
Вы можете представить себе изменение одного из этих классов или систем классов, а затем беспорядок, потому что вы также должны изменить все свои модели. В то время как контроллеры являются посредником между входом клиента и данными: в этой роли они являются правильными валидаторами приведенных выше примеров и, вероятно, многими другими.
Принимая во внимание другие ответы (и некоторые исследования), если вы должны проверять данные с помощью правил, таких как непустые поля, проверки подлинности электронной почты и т. Д., Контроллер не должен пропускать эти данные через себя, но если у вас есть такие правила, как «только пользователь с репутацией более 150 может проголосовать за ответ », вы должны сделать это на уровне модели.
Если вы хотите иметь проверку бизнес-правил, я советую вам иметь такой объект, как шаблон бизнес-объекта , причем в любой части программного обеспечения, когда вы хотите «проголосовать за ответ», ваша бизнес-логика сохранена и централизована.
Это интересная теоретическая дискуссия, но если мы сосредоточимся на том, что вопрос был поставлен в контексте Codeigniter (CI):
В CI вы можете указать правило пользовательской проверки следующим образом:
$this->form_validation->set_rules('email', 'Email', 'required|callback_my_validation');
В этом случае вы должны определить публичную функцию, называемую «my_validation», которая должна возвращать true или false, а фреймворк добавит ошибку (если возвращается false) в стек ошибок.
Итак … если вы поместите этот код в контроллер, вы непреднамеренно разоблачаете публичный URL-адрес , то есть можно было бы называть что-то вроде « http://yoursite.com/my_validation » (я не думаю, что вы намереваетесь ). Единственный способ защитить этот URL-адрес – зайти в файл «routes.php» и предотвратить доступ к этому URL-адресу. Это не кажется практичным и, похоже, указывает нам на то, что разработчики CI намеревались обработать валидацию в модели.
Модель должна проверять свои собственные данные.
Скажем, у вас есть модель контактов, для которой требуется только имя и номер телефона. Он должен подтвердить, что имя и номер телефона заполнены.
Однако, если эта модель контактов является частью цитаты, вам может потребоваться полное имя и адрес электронной почты.
В этом случае вы можете либо расширить модель Contact (чтобы быть модель QuoteContact), либо добавить дополнительные проверки, либо выполнить дополнительные проверки в модели Quote.
Вы должны написать свои модели, чтобы их можно было повторно использовать в других приложениях (даже если они никогда не будут), поэтому они должны быть независимы от контроллера. Если проверки находятся в контроллере, вы теряете эти проверки, если вы переключитесь на версию командной строки.
Если вы проверяете форму на сервере с помощью codeigniter, то она проверяется в контроллере
Вам нужно включить библиотеку form_validation, используя autoload, как это
$autoload['libraries'] = array("form_validation")
ИЛИ непосредственно вы загружаете в контроллер
$this->load->library('form_validation');
Затем вы устанавливаете правило проверки для каждого поля формы
$this->form_validation->set_rules('username', 'User Name', 'required'); $this->form_validation->set_rules('useremail', 'User Email', 'required|valid_email');
Если какая-либо ошибка найдена после проверки поля формы, то она улавливается в функции проверки
if ($this->form_validation->validate()) { //return back to form } else { //successful validate all field }
Существует еще один угол, на который это не распространяется в других ответах. Это зависит от того, что вы говорите, что вы Controller / View ! Если это Javascript, который проверяет правильность как тип пользователя, по соображениям безопасности вы также должны иметь валидацию в своем бэкэнде (это может снова быть в контроллере вашего бэкэнда или модели, потому что любой может просто нажать Data через Ajax без браузера.
По соображениям производительности вы также должны иметь валидацию в своем внешнем контроллере / представлении, потому что вы не хотите ударять свою базу данных каждый раз, когда пользователь выбирает недопустимую дату рождения или что-то в этом роде.
Поэтому, помимо теоретической основы валидации в M, V и / или C, вы также должны учитывать практичность frontend vs backend независимо от MVC.
Моя личная рекомендация – не ограничивать себя только одним уровнем проверки. Неверная проверка (например, пример подтверждения пароля, упомянутый в других ответах) может иметь серьезные последствия для архитектуры.