MVC PHP: манипулирование данными в цикле просмотра или в цикле контроллера (т. Е. 1 цикл или 2 цикла) - PullRequest
3 голосов
/ 21 сентября 2011

Меня всегда беспокоило то, что для манипулирования массивом используется более одного цикла.

Я имею в виду, что в контроллере данные выбираются из БД через модель. Допустим, мы показываем список пользователей, и каждый пользователь имеет статус (1,2,3 соответствует проверенному, непроверенному, заблокированному соответственно). На каждой итерации цикла статус будет проверяться и отображаться с помощью другого запроса к базе данных (в этом примере забудьте о присоединениях mysql).

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

- ИЛИ -

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

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

Ответы [ 3 ]

2 голосов
/ 21 сентября 2011

Я бы сделал это ни в представлении, ни в контроллере, а на модели.

Я объясняю:

  • Работа вашего контроллера заключается в получении списка ожидаемых пользователей, проверке ACL и т. Д. *
  • Ваша задача - представить эти данные в элегантной форме
  • Задание вашей модели предназначено для извлечения / хранения данных из базы данных и обеспечения целостности. Userstatus - тоже модель для меня.

Моя конфигурация делает это довольно простым, я использую усы (порт Php) для просмотра, что позволяет мне вызывать методы из моих моделей непосредственно в представлении. Я написал свой собственный ORM для своих моделей, поэтому у меня есть обертки.

Для меня такой код будет выглядеть так:

// Controller
$template = new Template('pages/users.html');
$template->users = mUser::find(); // return array of mUsers instances
echo $template->render();

// View
{{#users}} <!-- For each user -->
  {{getName}} has status {{#getStatus}}{{getStatusName}}{{/getStatus}}<br />
  <!-- getStatus is a method from mUser model, that return a mUserStatus instance -->
{{/users}}

/* More explain on the view syntax
{{name}} = $user->getName() (return string)
{{getStatus}} = $user->getStatus() (return instance of mUserStatus);
{{statusName}} = $user->getStatus()->getStatusName();
*/

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

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

Надеюсь, это поможет.

1 голос
/ 21 сентября 2011

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

Но, как вы сами отметили, это выбор реализации.

Также обратите внимание, что многократные обращения к вашей базе данных плохо влияют на производительность. Ваш пример - типичная проблема n + 1, означающая, что у вас есть 1 «верхний» запрос выбора, а затем еще N запросов для каждой строки в вашем первом наборе результатов. Если вы сталкиваетесь с такой проблемой, всегда пытайтесь решить ее на уровне БД.

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

0 голосов
/ 21 сентября 2011

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

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

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