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

MVC: Должен ли я вводить правила проверки формы в контроллер или модель?

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

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

Какой из них правильный подход с точки зрения 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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

  • Вид: Клиентская сторона (проверка javascript, html5 и т.д.). Это обнаруживает очевидные ошибки и пропуски до того, как данные попадают в контроллер, теряя время пользователя и вызывая ненужную загрузку страницы, если есть ошибки.
  • Контроллер. Это ваш уровень Форма. Контроллеры обычно предназначены для непосредственного ввода ввода и отправки его в модель. Очень редко, что каждое поле в вашей форме имеет непосредственно связанный столбец в вашей базе данных, вам обычно нужно каким-то образом изменить данные, прежде чем передавать его в модель. Просто потому, что у вас есть поле, которое нужно проверить, называется "подтверждать электронную почту", это не значит, что ваша модель будет иметь дело с "подтверждением электронной почты". Иногда это будет окончательный шаг проверки.
  • Модель. Это ваша последняя линия защиты для проверки и, возможно, ваша единственная проверка в случае отправки данных в модель без ее непосредственного ввода из сообщения формы. Существует много раз, когда вам нужно отправлять данные в БД из вызова контроллера или с данными, которые не являются пользователем. Мы не хотим видеть ошибки БД, мы хотим видеть ошибки, вызванные самим приложением. Обычно модели не должны иметь дело с данными $_POST или пользователем напрямую, они должны получать данные от контроллера. Вы не хотите иметь дело с бесполезными данными здесь, как подтверждение по электронной почте.

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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

Ответ 6

Это интересная теоретическая дискуссия, но если мы сосредоточимся на том, что вопрос был задан в контексте 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 намеревались обрабатывать валидацию в модели.

Ответ 7

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

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

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

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

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

Ответ 8

Если вы проверяете форму на сервере с помощью 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 
}

Ответ 9

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

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

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

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