Вопрос MVC: Должен ли я поместить правила проверки формы в контроллер или модель? - PullRequest
50 голосов
/ 13 апреля 2011

С одной стороны, валидацию формы можно рассматривать как часть логики приложения и, следовательно, принадлежность к модели.

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

Какой подход является правильным с точки зрения MVC?

P.S Моя проверка формы фактически состоит только из написания списка полей, их правил и передачи его в библиотеку проверки формы, которая возвращает 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

Должно ли это быть вставлено в контроллер или модель?

Ответы [ 9 ]

72 голосов
/ 14 апреля 2011

В идеале вы хотите 3 уровня проверки:

  1. Просмотр: Клиентская часть (JavaScript, проверка HTML5 и т. Д.). Это отлавливает очевидные ошибки и пропуски до того, как данные попадают в контроллер, тратя время пользователя и вызывая ненужную загрузку страницы в случае ошибок.
  2. Контроллер : Это ваш Форма слой проверки. Контроллеры обычно предназначены для непосредственной обработки ввода и отправки его в модель. Очень редко, когда каждое поле в вашей форме имеет непосредственно связанный столбец в вашей БД, вам обычно нужно каким-то образом изменять данные перед передачей их в модель. То, что у вас есть поле, которое необходимо подтвердить, называется «подтвердить электронную почту», не означает, что ваша модель будет иметь значение «подтвердить электронную почту». Иногда это будет последний шаг проверки.
  3. Модель : Это ваша последняя линия защиты для проверки, и, возможно, ваша единственная проверка в случае отправки данных в модель без , поступающих непосредственно из сообщения формы. Во многих случаях вам нужно отправлять данные в БД из вызова контроллера или с данными, которые не вводятся пользователем. Мы не хотим видеть ошибки БД, мы хотим видеть ошибки, генерируемые самим приложением. Модели обычно не должны иметь дело с данными $ _POST или пользовательским вводом напрямую, они должны получать данные от контроллера. Вы не хотите иметь дело с такими бесполезными данными, как подтверждение по электронной почте.
19 голосов
/ 13 апреля 2011

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

Мне кажется, это очевидно, но я бы с удовольствием выслушал оппонентов.

12 голосов
/ 13 апреля 2011

Я бы сказал, что код проверки формы должен быть в контроллере (а не в модели) в большинстве случаев.

Madmartigan лучше всего выразил это в своем комментарии выше "Проверка формы! == Проверка данных. Не все формы взаимодействуют с моделью"

Веб-формы логически являются частью представления / контроллера MVC, так как пользователь взаимодействует с ними в представлении.

5 голосов
/ 28 июля 2013

Кажется, что все всегда говорят, что модель передает этот вопрос, который имеет свои достоинства (по сравнению с противоположным), но я думаю, что ответ на этот вопрос более тонкий. Проверка правильности данных должна выполняться на модели.

Но существуют другие типы проверки , например, была ли форма отправлена ​​с неожиданными полями (в целях безопасности, очевидно) или имеет ли пользователь разрешение на выполнение запрошенной операции. Помещая эти типы проверки в модель, она скрепляет модель (абстракцию данных), чтобы полностью отделить вещи, например, как работает пользовательская система или как оценки форм оцениваются в целях безопасности.

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

2 голосов
/ 24 декабря 2013

Это интересная теоретическая дискуссия, но если мы сосредоточимся на том, что вопрос был задан в контексте 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-адрес - это зайти в файл "rout.php" и запретить доступ к этому URL-адресу. Это не кажется практичным и указывает нам наНаправление, которое разработчики CI намеревались обрабатывать в модели.

2 голосов
/ 27 февраля 2012

Принимая во внимание другие ответы (и некоторые исследования), если вам нужно проверить данные с помощью правил, таких как непустые поля, проверка электронной почты и прочее, Контроллер не должен пропускать эти данные через себя, но если у вас есть правиланапример, «только пользователь с репутацией более 150 может проголосовать за ответ», вы должны сделать это на уровне модели.

Если вы хотите проверить бизнес-правила, я советую вам иметь такой объект, как Шаблон бизнес-объекта , при этом в любой части программного обеспечения, когда вы хотите «проголосовать за ответ», ваша бизнес-логика сохраняется и централизуется.

1 голос
/ 29 ноября 2011

Модель должна проверять свои собственные данные.

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

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

В этом случае вы можете либо расширить модель Контактамодель QuoteContact) и добавьте больше проверок, или вы можете выполнить дополнительные проверки для модели Quote.

Вы должны написать свои модели так, чтобы их можно было многократно использовать в других приложениях (даже если они никогда не будут), чтобы они не зависели от контроллера.Если проверки находятся в контроллере, то вы потеряете эти проверки, если переключитесь на версию командной строки.

0 голосов
/ 12 ноября 2014

Существует другой угол, на который это не распространяется в других ответах. Это зависит от того, что вы говорите, Controller / View есть! Если это Javascript, который проверяет проверку как тип пользователя, по соображениям безопасности у вас также должна быть проверка в вашем бэкэнде (это снова может быть в контроллере вашей бэкэнда или модели потому что любой может просто передать данные через Ajax без браузера.

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

Таким образом, помимо теоретической основы валидации в M, V, и / или C, вы также должны учитывать практичность фронтэнда и бэкенда независимо от MVC.

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

0 голосов
/ 29 июля 2014

Если вы проверяете форму на сервере, используя codeigniter, тогда она проверяется в контроллере

Вам необходимо включить библиотеку form_validation, используя автозагрузку, подобную этой

$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 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...