MVC: Controller, View Question
I'm playing around with MVC (in PHP) and I created my framework based on this basic tutorial. I still don't like using MVC, but I think I should get some experience in it, and maybe I'll end up liking it.
Anyway, my question is, if in a "UserList" controller, you had a SQL query that went out and fetched all 1000 users in the site. The Controller then does some stuff to all the rows (maybe checking to see if they logged in in the last year, or something like that). In your View/template, you want to print out that manipulated list of Users. In your View, you'd have to loop through all 1000 users again? Is that the right way of doing it? Looping twice through lists doesn't make a lot of sense to me. Is there another way to do it (besides the Controller generating parts of the View as it loops through the rows of users)?
pr0gr4mm3r posted this at 16:59 — 25th June 2008.
He has: 1,502 posts
Joined: Sep 2006
I would first say that coding in the MVC form has made my websites way more organized. I tried starting by creating my own framework from scratch, and that worked for a couple projects, but I found that using an existing framework is much easier. Try using CodeIgniter. It is very well documented and even has a couple screencasts to help you get started.
With your specific question, this is a case where you want to do all your filtering, tweaking, ordering, etc in your SQL query. Then you only loop through it once in your template. That was why I had that goal earlier.
The best way to do it is run the query that fetches the users, and send that result set to your view. Then loop through it there.
teammatt3 posted this at 19:22 — 25th June 2008.
He has: 2,102 posts
Joined: Sep 2003
Hmm, I wasn't expecting that answer . But lets make the crazy assumption that manipulating list in SQL isn't an option (for whatever reason). So you have to loop through the result and perform some operation on each row, and then pass that over to the view. Is there any way to avoid looping twice through the result without constructing some of the view inside the controller?
Well, maybe this isn't the best example. But I have this idea in my head that separating the controller and view will sometimes result in having to do the same operation twice, once in the controller, once in the view. Is that true? Or can it always be avoided?
For me, MVC looks like a mess. If I find a bug on one of my MVC generated pages, I have to search through a controller, a view, maybe some "helper function" and more crap like that. For me, there's a point where all that abstraction turns things into spaghetti. I design my pages so that the controller and view are right there together. Then I have one single file that holds all my classes and another that holds functions. If I find a bug, I know right where the problem could be. If a programmer came onto one of my projects, he would very easily be able to figure out how things are working, but when you use a framework, the programmer has to know how to program AND he also has to figure out how your framework works. How long did it take you to get used to a framework?
teammatt3 posted this at 01:49 — 26th June 2008.
He has: 2,102 posts
Joined: Sep 2003
Ah ha, here's a more practical example (that I'm facing right now).
I have a list of school courses in a database. When the user comes to the course list page, I run a query in the DB that returns the list of courses. A school course is an object, so for each course that is returned, I create a new Course object. How can that be achieved efficiently using MVC?
Non-MVC (un-tested)
<?php
while($course_row = $db->fetch($result))
{
$course = new Course($course_row);
echo "<tr>";
echo "<td>" . $course->getName() . "</td>";
echo "<td>" . $course->getQuestionCnt() . "</td>";
echo "<td>" . $course->getPassed() . "</td>";
echo "</tr>";
}
?>
How can something like that be done keeping the view and controller part separate?
Oh, and if you guys have any good MVC resources, please share. I'm having a tough time with this.
pr0gr4mm3r posted this at 04:25 — 26th June 2008.
He has: 1,502 posts
Joined: Sep 2006
I think there is a learning curve when a programmer is debugging someone else's code whether a framework was used or not. Everybody has their own style and techniques.
Wells-it.com is my first project with CodeIgniter. I started it back in March, and I will be launching it in a few weeks (hopefully). The framework learning curve was a couple weeks, but after using this, it makes me cringe going back to older projects. This new website includes a CMS (blog, pages, comments) from scratch, user accounts & registration, contact forms, and small project management tools.
I agree with you to a point. I have believed for a long time that separating HTML from the main PHP scripting is a mucho important thing to do. I have used template systems for quite some time, and it greatly simplifies things, so I believe people should do at least that. That's only a "VC" (View-Controller) approach. Should you take it a step further and separate the data logic from the controllers? Depends on the situation and personal preference. With that in mind, I originally found it difficult to draw the line between the view and the controller because I didn't see the point, like your dilemma of looping through the data twice. That's why I use no PHP in my views; they are strict HTML templates.
Regarding your specific question, that code you posted would go in your view file. The code to get that $result goes in the controller or model.
I went through that tutorial you posted, and it honestly looks overcomplicated. Designing your own framework is unnecessary because there are so many out there already, and they have already been checked for security issues and bugs by thousands of users.
For me, I learn by example. That's why I dove into a framework without really even knowing what MVC stood for. The only framework I've tried so far is CodeIgniter. I had no reason to try others because this one has worked so well.
teammatt3 posted this at 15:24 — 27th June 2008.
He has: 2,102 posts
Joined: Sep 2003
Thanks for the info. CodeIgniter seems ok. I watched the videos and they really helped. I just hate how they abstract DB queries so much but once again, maybe I'll learn to like it.
Abhishek Reddy posted this at 06:59 — 29th June 2008.
He has: 3,348 posts
Joined: Jul 2001
The first half of Tony Marston's PHP MVC page has a pretty good introduction to the concepts. His implementation is illustrative too, though it's not PHP5.
I don't see the problem with multiple passes on the data set. If you separate the work done per row between two loops, then each loop is doing less work. And since they are not nested loops, the total time complexity ought to remain roughly the same. Also, because the view only reads data (and assuming you pass data by reference, not copy) there should be no growth in space either.
The real cost here is in object deserialization (creating many new Course objects on every query) in the first loop. It's actually unfair on the view and controller to worry about it, as the V-C relationship should not care how the model is instantiated. If you are bothered by that cost, then consider using long-lived objects (caching/pooling/reuse), rather than having the model rebuilt on every query.
In some simple cases, it may seem like the structure is duplicated. But as your models and queries get more complicated, you'll find less mirroring of structure between atomic controller operations and highly composed view operations.
It's okay for basic idioms like "foreach" to recur. (Actually, a lot of the boilerplate could well be eliminated if the language supported macros or first-class functions, but that's not an option with PHP.)
MVC isn't a silver bullet. You can still write spaghetti code within an MVC pattern. Admittedly, the flow of control can seem hard to track at first, but it's a small upfront cost for a large long-term gain. Consistency, conventions, and good debugging/tracing help.
I'm curious: how does your templating work? And is this related to CodeIgniter?
pr0gr4mm3r posted this at 16:56 — 29th June 2008.
He has: 1,502 posts
Joined: Sep 2006
Not really. I basically replaced the views with the templates. Well, technically, I guess I run a MVCT (Model View Controller Template) approach , but all my views do is load the templates for the specific page, merge the variables (sent from the controller), and show the page.
Want to join the discussion? Create an account or log in if you already have one. Joining is fast, free and painless! We’ll even whisk you back here when you’ve finished.