Как правильно обрабатывать данные $POST в MVC?


У меня обычная ситуация с MVC в моей системе PHP: Controller получает запрос от View, содержащий данные $_POST. Теперь у меня есть три способа обработки данных:

A) Controller вызывает только Model, а Model обрабатывает данные $_POST.
б) Controller преобразует данные $_POST в переменные и передает их в Model.
c) Controller преобразует данные $_POST в объект домена Model и передает объект только Model.

В настоящее время я следую варианту А, но я считаю, что это неправильно, поэтому я подумываю об использовании варианта C.

Итак, согласно MVC, как правильно обрабатывать данные $_POST?

РЕДАКТИРОВАТЬ На данный момент я не использую никакой фреймворк MVC.

РЕДАКТИРОВАТЬ 2 Как правило, один и тот же Controller обрабатывает запрос из браузера, веб-службы, автономного приложения и т. Д., Или у каждого из них есть свой собственный Controller?

Author: Renato Dinhani, 2012-11-13

5 answers

Лучший вариант - использовать #2 подход, с некоторыми изменениями.
Я бы написал это примерно так:

public function postLogin( $request )
{
     $service = $this->serviceFactory->build('Recognition');
     $service->authenticate( $request->getParam('username'),
                             $request->getParam('password') );
}
// Yes, that's the whole method

На самом деле нет необходимости создавать переменные, если вы использовали что-то вроде экземпляра Request для абстрагирования ввода пользователя.

Кроме того, вы можете заменить метод Request::getParam() чем-то вроде Request::getPost(), хотя я пришел к выводу, что в правильно структурированном приложении параметры GET иPOST не следует использовать одно и то же имя.

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

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

О других вариантах:

  • Контроллер вызывает только Модель, и Модель обрабатывает данные $_POST.

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

    Если вы используете его со слоем модели, ваш код становится привязан к веб-интерфейсу и даже к определенному методу запроса.

  • Контроллер преобразует данные $_POST в объект модели и передает объект только модели

    Не совсем уверен, что вы имели в виду, говоря это. Кажется, вы говорили о создании экземпляра абстракции, которая будет содержать запрос пользователя. Но в этом случае контроллер становится ответственным за создание/создание указанной структуры, что нарушило бы СРП.

Заключительные примечания:

Одна вещь, которую вы должны понимать, заключается в том, что в контексте веб-приложений MVC Пользователем вашего приложения является браузер. Не вы. Браузер отправляет запрос, который обрабатывается механизмом маршрутизации и распространяется контроллером. И view выдает ответ вашему браузеру .

И еще одно: модель не является ни классом, ни объектом. Модель представляет собой слой.


Обновление

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

У вас должен быть единый контроллер, который работает со всеми формами приложений. Но это только при условии, что вы фактически используете одно и то же приложение для всех 3 вариантов использования.

Для этого есть два условия:

  • вам нужно абстрактный экземпляр Request, который контроллер получает
  • представление должно быть создано вне контроллера

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

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

 24
Author: tereško, 2017-05-23 10:34:11

Когда-то была трехуровневая архитектура приложений.

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

В первые дни MVC в PHP слой модели на самом деле был просто объектами домена, называемыми моделями для этой цели. Некоторые предпочитали иметь так называемые тонкие модели, которые обеспечивают только представление данных OO (что упрощает сохранение). В в этом случае контроллер перегруппирует так называемые действия, содержащие основную часть обработки, связанной с HTTP-запросом (контроллер fat).

Другие внедрили большую часть указанной обработки в объектную модель с помощью специальных методов (модель fat).

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

Интересный вопрос: как вы справляетесь с действиями, влияющими на несколько объектов домена? Где вы находите логику для этого?

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

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

  • запрос сначала превращается в объект
  • этот объект маршрутизируется с помощью объекта маршрутизации
  • он передается контроллеру
  • контроллер передает запрос службе, заинтересованной действием, которое создает объект ответа

Затем задание службы прерывается в несколько этапов:

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

CakePHP - еще один популярный фреймворк который следует аналогичным концепциям: простые контроллеры и службы, инкапсулирующие объекты домена.

Смотрите этот вопрос для лучшего понимания общих концепций.

Смотрите этот другой вопрос для других ответов.

Спасибо Терешко за его неоценимый вклад в этот вопрос.

 3
Author: didierc, 2017-05-23 10:27:23

Я использую Zend и следую

2-й вариант.

Пример регистрационной формы

Шаг-1 формы отправляют мне значение post указанному контроллеру

Шаг-2 я проверю значения формы, например (почта и URL-адрес и пустые значения сообщений), с помощью проверки на стороне сервера.

Шаг -3 отправьте проверенные данные post либо в переменной, либо в целом в модель.

Шаг 4- контроллер вызывает модель.

Шаг -5 модели вставляют значения post и создают нового пользователя.

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

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

 but i prefer to keep different controller for differnt user request and user types

 it helps in keeping code readable managebale .
 1
Author: Rinzler, 2012-11-22 13:54:38

Посмотрите на некоторые фреймворки MVC.

Например, в Yii вы можете написать такой код внутри действия :

$model = new Model();
if(isset($_POST['Model'])) {
    $model->attributes = $_POST['Model'];
}

Обратите внимание, что все attributes вашей модели должны быть пройдены через правила проверки. В Yii проверка применяется во время (на самом деле, до) $model->save()

См.:

  1. http://www.yiiframework.com/doc/guide/1.1/en/form.model#securing-attribute-assignments
  2. http://www.yiiframework.com/doc/guide/1.1/en/basics.mvc
 0
Author: Vladimir Posvistelik, 2012-11-13 11:26:33

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

Пример: одна и та же модель может использоваться веб-интерфейсом и веб-службами. В Интернете $_POST действителен, но для веб-сервисов его нет. Таким образом, модель не заботится о том, как будут получены данные, а только о том, как их хранить и загружать.

Yii определенно является чистой реализацией MVC.

 0
Author: Shiv, 2012-11-15 13:48:34