Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC PHP: Data manipulation in View loop or Controller loop (ie. 1 loop or 2 loops)

Something that has always bothered me is doing more than one loop to manipulate an array.

What I mean is, in the controller the data is fetched from the DB via a model. Lets say we are showing a list of users, and each user has a status (1,2,3 equates to verified, unverified, banned respectively). Within each iteration of the loop the status would be checked and displayed via another Db query (forget mysql joins in this example).

Now, would you do that in the controller within a loop, and then perform another loop in the view with all the data already fetched and pre-formed ready for display (therefore resulting in 2 loops).

--OR--

Would you just do it in the view therefore resulting in the one loop but with model calls from the view. I understand that this is ok in the strict MVC pattern but its frowned upon generally.

It seems silly to loop twice but then its tidier as all the data manipulation is kept within the controller.

like image 589
Lee Overy Avatar asked Nov 03 '25 07:11

Lee Overy


2 Answers

I would do that nor in the view or the controller but on the model.

I explain :

  • Your controller's job is to retrieve the expected user list, check ACL, etc...
  • Your view's job is to present this data in an elegant form
  • Your Model job's in to fetch/store data from Database and ensure integrity. Userstatus is a model too for me.

My configuration make this pretty easy, I use mustache (Php port) for view, which allow me to call methods from my models directly in view. I wrote my own ORM for my models, that way I have wrappers.

Such code would look like that for me :

// 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();
*/

You may want to have request caching for each model instances in request level so that you never runs a request twice times if not needed.

That seems more natural to me than to delegate it to controller. I try to put business intelligence on controllers, there is no need for intelligence nor programmer intervention to retrieve a status name for each user.

I Hope it help.

like image 132
Sébastien VINCENT Avatar answered Nov 04 '25 23:11

Sébastien VINCENT


In my opinion logic that manipulates the data you're returning, should be located in the controller. Logic that manipulates the representation of your data can be located in the view. So I would go for the second option.

But, as you pointed out yourself this is a choice of implementation.

Also note that multiple round trips to your DB are bad for performance. Your example is a typical n+1 problem, meaning that you have 1 'top' select query and then N more queries for each row in your first result set. If you encounter such a problem always try to solve them on the DB level.

Another note I would like to add is that in your example you're storing status explanations in the DB. If you want to provide your applications in other languages, this might prove to be a problem. But this is beyond the scope of your question :)

like image 36
thomaux Avatar answered Nov 04 '25 22:11

thomaux



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!