Write your own MVC with PHP

JREAM - your use of defines makes me cringe, especially given that you put many security values in them:

Uhg… Learning from Wordpress’ example I see.


ON topic - MVC is something I’ve practiced in most of my code since before I started writing PHP. In PHP with all the possible avenues of attack thanks to it being a on-the-fly interpreted language, MVC makes perfect sense and IMHO is how all code SHOULD be written.

Though I prever to put the C FIRST, because the controller is what should be called FIRST! It goes hand in hand with my routing ALL requests through the root index.php - my controller. Also makes doing friendly URL’s a hell of a lot easier later on since you can just redirect all calls to non-static files to index.php and explode $_SERVER[‘REQUEST_URI’]…

You have to think about the controllers job - it’s traffic cop, an air traffic controller. It should decode the user request, load the appropriate models to process the data, and then handle the transfer of said data or responses for the requests to the view - in that order.

That separation of tasks is also a perfect opportunity to harden the system by not using globals for everything. Even my index.php has everything wrapped in functions, a dummy wrapper for require_once that breaks scope of locals so values HAVE to be passed via the function handler (I usually do so by reference so memory use is kept under control) - even the database connection if you use PDO can be restricted in scope to local.

SCOPE is very important if thinking security, especially in a scripted language… One of the whole reasons to use MVC is to keep you data processing isolated from the template. There is no reason for your View/Template to EVER need database access - so why would you pass the values to said functions or make them global in scope? Is it any wonder that EVAL and user uploads are such a risk?

That’s security programming 101 - never put security related info into globals or defines. It’s also the number one mistake even many seasoned developers seem to make as if they’ve never even heard of the concept.

In a lot of ways that is why I find many object based MVC’s to in fact miss the point of using MVC in the first place, as they ‘round robin’ back and forth between the template and the data, - instead of just processing ALL the data, then showing all the data… and worse they store everything in the object in a manner at which it might as well all be globals in the first place! I’ve seen people claiming their code was MVC where the template (view) was even calling their object based data handlers directly. “Oh, but it’s in an object so it’s separate”

COMPLETELY MISSING THE POINT. Calling the data handler is the CONTROLLERS job, not the VIEW’S… I would allow that the other direction, the MODEL calling the VIEW, but I really prefer a FULL separation of the two as neither should have access directly to each-others functionality or values. That’s not just a security thing, that defeats the point of having them “separate” in the first place!

It also doesn’t help to load EVERY model as a single file on every call… That’s loading tons of code that probably isn’t even going to be executed… While that’s not really an issue in a compiled language, PHP is interpreted and every piece of code has to go through the bytecode compiler, and consumes memory if run or not. This is more data to shove in/out of the cache on each request run or not, and in general why I dislike objects in interpreted languages with rare exceptions.

… and MVC does NOT need objects to work. Quite the contrary if you have at run-time includes available… Though yes, objects ARE nice to restrict scope, but if the class is globally available anyways, what’s the difference between locals in a function and those in a object?

Though I suppose my approach if you flowcharted it would be C > M > C > V. Controller processes the request, handles any security, calls the appropriate model which returns the output/data to the controller. It’s then the controllers job to call the view/template. It does end up a bit more memory hungry than letting the Model call the View directly, but it generally runs faster since you can concentrate on each task instead of switching gears mid-processing from retrieving data to outputting data.

Besides, RAM is cheap these days. When I can get a dedicated dual core atom 330 server with 2 gigs of RAM for $60/mo, I’m not sweating a little extra RAM overhead if it means less CPU overhead and more consistent disk access patterns.

In a lot of ways it’s like practicing separation of content from presentation in your HTML and CSS. Your template or the code behind the template has no business going to the database, and your database access has no business outputting results. Each has their own job, let them do it.

I do kind-of break the controllers separation by letting it handle sessions, user logins and database connections - but I feel that’s more true to the intent since the controller can then determine does the user have the rights to access the model - what models should even be ALLOWED access to the database, the data structure used to pass information, what PARTS of the data structure, etc, etc.

In any case, it really is a better way of coding making everything simpler - from easy reskinning (to the point you can even let people use PHP in their skins with ZERO worries of them screwing up the data, so screw the overhead of ‘templating systems’ like smarty), to not having to wade through output to debug a data handling issue, to having your code end up more secure ‘by default’.

I’d argue that this is entirely wrong. The view SHOULD access the model and request what it needs. Without this, you lose the real power of MVC, it makes your controllers do far too much. If you’re just displaying data there is no reason that the controller needs knowledge of the data. The controller passes the model to the view and the view requests the desired information.

From the MVC article on wikipedia: “A view queries the model in order to generate an appropriate user interface (for example, the view lists the shopping cart’s contents). The view gets its own data from the model. The controller may (in some implementations) issue a general instruction to the view to render itself. In others, the view is automatically notified by the model of changes in state (Observer) which require a screen update.”

In php it’s slightly different and the model can’t realistically perform a callback on the view because the view only ever has one state throughout its lifetime, but the principal stands.

As an example, a simple forum. The controller would initialise the view and pass the model to it. The view would perform an action (predefined by the view) on the model… e.g. get the latest 20 posts. It would then display it. There’s no reason for the controller to tell the model what the view requires, otherwise you’re just adding an extra step.

See to me that defeats the point of having them “separate” in the first place. The “views” job is to show the data for user interaction. It shouldn’t have access to the model - at that point you might as well go back to old-school spaghetti coding.

But that’s my problem with most peoples way of applying the MVC paradigm… but then you do have to adapt it to the nature of the application.

Of course, a lot of my interpretation could simply come from my first 20 years of programming having drilled into my head “far calls bad… Far calls bad, avoid unnecessary procedures”

So constantly handing off from view to model to view to model to view to model isn’t exactly my idea of good programming. Let the controller figure out what we need, let the model get it, then have the view show it. Three simple steps.

You do it the way you say (and many others approach it) the view ends up going to the model every five lines… I need the TITLE tag contents, call the model… I need the site title for the H1, call the model, I need to build the menu, call the model. I need to display the page contents, call the model, I need the stuff to generate in each side-bar item, call the model, display, call the model, display, call the model, display… Doesn’t it make more sense to just let the controller tell the model “build this”, let the model do it’s job uninterrupted, then call the template to show everything? Worse it makes the VIEW control the logic flow of the application - which defeats the point of HAVING a controller in the first place!

Though much of that re-interpretation of it comes from that there is no real-time interaction between the user and the page since we’re generally talking websites. What’s being requested is available to the controller the moment it’s called, and it’s not like the ‘view’ changes until you send a new page… So a lot of the things like going back and forth between view and model aren’t even going to come up in your code (or at least shouldn’t)

Maybe I should come up with a cutesy acronym for my approach since it is a bit different? Controller, Acquisition, Show, CAS? Sounds good, reminds me of Close Air Support. Eh, not sure about the middle word. One of my problems with MVC is it’s terminology isn’t very clear… “model” is pretty damned vague, want to avoid that. Maybe CDS. Controller, Data, Show.

How was it Wiezenbaum put it? “Any idiot with a primary school education can put out a whitepaper…:smiley:

Well, while sometimes it ‘feels’ better to have the controller have exclusive access to the model. It seems cleaner to begin with, you have a nice one way data flow but you end up in a situation where the controller contains display logic. Should the controller be telling the view how many records to display or how to sort them? The view can have options set by the controller but when the controller is doing these kind of actions it severely reduces the re-usability of the view (every time you want to reuse it you have to perform the same requests to the model in each controller).

By giving the view access directly to the model you no longer need to modify the controller when the client moves the goalposts requirements change. If you view needs to be modified to, for example “also put the billing address on the invoice” the view can request the address from the model without having to have it assigned by the controller… and every other controller which uses the view.

It depends on whether you want thin views or thin controllers. I’d rather keep my controllers to a minimum as they’re not going to be re-used. The more I keep out of the controller, the more code I can re-use.

Edit: PHP makes MVC less intuitive because of the single request -> response method. If you think about it in terms of desktop application it makes more sense.

Imagine a windows form, the controller initialises the model and the view, the view is populated from the model. The user modifies the data and presses save. Does this need to go through the controller? All the information is in the UI, if the view has access to the model it can simply send the data back to it. There’s nothing new here, the controller has no real reason to do anything.

Actually the DATA returned by the model should be telling the view how many to show… while the controller should be telling the model how many to get… since it’s the controller. At least that’s how I see it, YMMV. Controller says get this many, model says “ok, here’s the data”, controller says to view “here’s the data, show it”

You could MAYBE kick out the middle man of the controller getting the data and instead have the model say to the view “here it is, show it” - other way around doesn’t make much sense to me since then it’s not “view”, it’s doing the controllers job.

Though in PHP I think of view as an output only element, since PHP, at least for writing web based software, is a “get it and show it” device without realtime interaction. To me the view shouldn’t be handling input since again, that’s the controller’s job.

It also means you can ‘stack’ results on the controller to be viewed all at once. Handy if you are working with a view not in sync with the data - that’s not so much of a php application of it, as more when dealing with graphics like in OpenGL or DirectX, where if for example vSync is on or you are using a frame limiter, you might have the input and physics running full bore while only calling ‘view’ when the display is ready. Very common in multithreaded simulators where you want input, data and calculation granularity higher than the output.

Part of the reason for that approach is the simple ability to throw out and use and entirely different view code without changing the logic structure of handling user input, data calculations, or data handling. You put any of that in VIEW and have VIEW calling it, you can’t have them run unchained.

where to me that’s just another field to be shown, so the view code should be smart enough to iterate the data gathered by the model and say “ok, I need to show this too”

Though admittedly, I have kind of a warped view on handling that.

Funny, I’ve got the exact opposite… more I can do the same way in the controller, the less my models have to do… More I do in the models, the less my view has to do.

Since for me the view’s only job is to take the data from an array and show it using semantic markup. It’s why when I pull data I generally also pull it’s TYPE. This is a text field, this is a date, this is a boolean - because what TYPE it is can be considered part of the data. That makes it so all the view has to do is format it with semantic markup.

MY approach to building a webform follows this - I have an array in whatever .module.php that says what fields are present, what order they should be shown in, what type of field it is, is validation required - the template (view’s) job is to go through that data and show it by type applying all the tags in a consistent manner. Again, WHAT’s to be shown is the models job, HOW it’s shown is the View’s. (that same array is also used by the model to process the returned POSTDATA, and hooks are present in the markup in the form of classes so javascript validation could be applied as well).

It’s the Vinnie Barbarino approach. Who? What? Where?

I agree wholeheartedly with that, part of what I said above… and the approach you are saying is fine for event driven programs you put together in a RAD like the various visual languages (hell, it’s pretty much HOW those work!). It breaks down in realtime applications, or as you noticed request/response ones which is why while you can still take the good ideas from it, in a lot of ways you have to change the picture a bit.

ESPECIALLY if you take the differences between interpreted and compiled languages into account.

Funny, I’ve got the exact opposite… more I can do the same way in the controller, the less my models have to do… More I do in the models, the less my view has to do.

The problem is that views are used in multiple places. In this scenario, when a view is changed, all the controllers which use it need to be updated. If I want a new controller which uses the view I need to do all the set up work again, rather than initiating the view and linking it to the model. There’s no reason the model can’t be substituted for another (and if you’re programming around interfaces it’s easy). Simply put, the controllers aren’t re-used so making them do as little as possible means less repeated code.

where to me that’s just another field to be shown, so the view code should be smart enough to iterate the data gathered by the model and say “ok, I need to show this too”

But where does it get the data from? Do you adjust your model to fetch more data in the same function call? What if that’s used elsewhere? What if it’s used in 10 different places all with slightly different data? That’s a lot of extra data being loaded in 9 other places.

Personally I haven’t come across any reason to create my own MVC framework. I have been using Symfony for quite some time now, having moved from CodeIgnitor and CakePHP, and have found little it couldn’t do while keeping processing time low.

MVC is not a rocket science people!

For many reasons I disagree deathshadow60. View not accessing Model? jeez~

This is MVC flow

Http requests -> Master Front Controller -> Business Controller -> Master Front controller -> retrieve and render view template -> Master Front Controller -> client’s browser.

When talking about Model. This object should contain the results of the Model DAO. So Business Controller access the Model DAO then passes the Model (Result) to the View. Model is the result! Ok I’m done. Time for more spaghtti code :rofl::rofl::rofl:

‘Business controller’ shouldn’t access Model DAO… it should initiate the model it and pass it to the view.The view then accesses the model to request the result. The controller shouldn’t be doing anything to do with business logic (e.g. fetching a result) This should be done in the model after it’s been passed to the view. In some cases the controller may set options on the view, but it shouldn’t directly govern how the model and the view interact.

just because you’re calling a function on the model from the controller doesn’t mean you’ve moved the business logic out of the controller.

A good example is pagination. If your controller is doing this:


$perPage = 10;
$page = $_GET['page'];
$users = $this->user->find('lastlogin < "2009-05-10"', $perPage, $perPage * $page);
$totalPages = $this->user->count('lastlogin < "2009-05-10"') / $perPage;
$this->view->assign('users', $users);
$this->view->assign('totalPages', $totalPages);
$this->view->assign('page', $page);

You have business/display logic in the controller and should be doing something more like this:


$this->view->assign('user', $this->user);
$this->view->assign('filter', 'lastlogin < "2009-05-10"');
$this->view->assign('page', $_GET['page']);

For several reasons:

  • You’ve removed the business logic from the controller
  • The view can now be much more easily re-used, without having to manually work out the options each time.
  • Now that the view has access to the model, you have much better control over what the view is doing. Perhaps the view should always add some extra filters, e.g. only users which aren’t deleted. Otherwise these extra filters needs to be added in each controller. Perhaps it has different filters based on the current user level? This is all display logic and should be in the view–not the controller.
  • The view controls its own error conditions, e.g. it’s easy to implement “Sorry, no records were returned but here’s some you may be interested in” because it can ask the model for something else. Otherwise you need this logic in the controller too.

I meant DAO as a Data Access Object. This will initiate a query from db and return model as a result. Perhaps this is what you meant by initiate and send to the view. Yes, I’m sending the result of DAO to the view. Yes I do have a controller that doesn’t have any business logic. That’s the Front Master Controller. This controller will pass onto corresponding specific business controller depending on the URL. Maybe my business controller has another name like business action class. But why couldn’t controller go to another controller? So if my business action class wants to pass along to another controller…then what would this class be? Controller or Action? I just call it controller. Maybe another name is Resource class if you will.

Definitely model should not contain any critical business logic. If it’s doing minor validation like length or require check then it’s justifiable. But, no processing like storing data into a DB is a definite NO NO!

I’m not sure I understand your architecture but no controller should contain business logic, it’s essentially there to initiate the model and the view.

If you’re calling a function in the controller which is getting data from the model and passing it to the view, you’re doing it wrong in most cases and adding an extra, unnecessary step.

The model should contain all the business logic. The view should contain all the display logic. The controller should just get those two connected.

edit: You’re in a similar position I was until I read this article

Thanks for the article. I only read about the
“Models Misunderstood” and I still stand that Model is definitely not the place to put business logic.

He says “company internal controls could dictate that purchase orders be subject to a single cash purchase limit of €500. Purchases over €500 would need to be considered illegal actions by your Order Model”

So now you’ve tied that all Order’s can not absolutely go over $500. But, let say you have a requirement that changes this. For example, if it’s a corporate customer limit is $50000, web customer is $1000, and POS is $500. Then what? Are you going to pass in the type of customer and do validation in the model? Why would the model care about the type of customer?? then let say we add “discount” logic that is seasonal. Are you going to pass in some special flag to indicate discounts? Model should not have anything beyond getters, setters, and maybe a validate method. only validations they should is like price should be a digit and greater than 0. Anyways, this is from my understanding and I’m sticking to it :slight_smile:

The problem is, you’re treating a model as if it’s a single entity in the system rather than a layer that consists of entities, data mappers, etc. This is a mistake I made too.

The order obviously needs to be linked to a customer at some point.

Oh, and the simplest solution:


class WebCustomer extends Customer {
    public $limit = 1000;
}

class CorporateCustomer extends Customer {
    public $limit = 50000;
}

//...

$order->setCustomer(new CorporateCustomer);

So where should the function call to the Model object be? in the View? That looks like spaggeti code. What we are talking about is a function, which belongs to the Model object, and pulling data from db. The call to that function should be in the Controller. Surely. Or am I missing something.

Why is it wrong to invoke a Model function returning a resultset, which is passed to the View for presentation? I thought that was neat, and in a way what deathshadow60 considered the best methodolgy. I tend to agree with him on that. Sometimes there are several db calls to get different data. i.e, pupulating title, sidebar, some other snigget(as deathshadow60 eloquently explained). the View going forth and back from the Model in order to fetch the said data again and again is not a good idea. It is no different than spaggeti code. Instead, have all these function calls in the Controller and pass the resultsets to the View in one go. The View should be able to present this neatly without worrying as to whether to have access to the Model directly or not. You may say cut the middeman, but no. The middelman(that is, the controller) is the most important aspect of the whole setup. Everything should go through it. Without the middleman, the model is borken.

Or have I misunderstood the whole thing?

Not that I’m a PHP programmer but I rather do

$order.setOrder(order);
$purchaseLimit = CustomerType.CORPORATE.limit;
$status = $orderService.processOrder($order, $purchaseLimit);

This makes the code more reusable. I didn’t need to create more classes and I think it’s more readable as well. Just as an exageration, let say there’s 100 types of customers… do you think it’s reasonable to create 100 models??? that’s crazy.

So where should the function call to the Model object be? in the View? That looks like spaggeti code. What we are talking about is a function, which belongs to the Model object, and pulling data from db. The call to that function should be in the Controller. Surely. Or am I missing something.

Why is it wrong to invoke a Model function returning a resultset, which is passed to the View for presentation? I thought that was neat, and in a way what deathshadow60 considered the best methodolgy. I tend to agree with him on that. Sometimes there are several db calls to get different data. i.e, pupulating title, sidebar, some other snigget(as deathshadow60 eloquently explained). the View going forth and back from the Model in order to fetch the said data again and again is not a good idea. It is no different than spaggeti code. Instead, have all these function calls in the Controller and pass the resultsets to the View in one go. The View should be able to present this neatly without worrying as to whether to have access to the Model directly or not. You may say cut the middeman, but no. The middelman(that is, the controller) is the most important aspect of the whole setup. Everything should go through it. Without the middleman, the model is borken.

Or have I misunderstood the whole thing?

All I’m suggesting is moving the call from the controller to the view, which decreases code repetition.

The View always has a contract with a model of some description. Whether it’s a primitive array or a complex object it requires the model to have specific data within it, this is naturally unavoidable. By using the Model directly, this contract is immediately fulfilled. If you’re passing primitives to the view, it has no way of knowing whether this contract is fulfilled until it breaks… or not. Even if your result set is a set of objects, the view cant know the set is correct (because it’s likely a primitive array containing objects) until it tries to use an object. By using the Model, the view can check this contract is fulfilled as the model is assigned to it.

Ignoring this, and assuming your controller always passes a valid data set you still lose re-usability. All the data fetching logic (the call to the model) has to be done on every controller using the view, as I demonstrated using pagination as an example this isn’t a good idea as it creates repeated code wherever the view is reused.

Where different models are needed, different models can be passed to the view.

How are you going to work out what type of customer you’re dealing with? $purchaseLimit = CustomerType.CORPORATE.limit; wont work… you’d need a 100 block if-else to work out the correct type…

Hi lauthiamkok,
I would consider using a pre-built framework or CMS such as ExpressionEngine that feels like a framework without having to dig into PHP - and you can expand the cms with your php skills if you like.
Learning the inner workings and the guts of app IS fun but it is also a huge time whole…no need to re-invent the wheel. :wink:
Considering that you are a designer by trade (and not a programmer) and if MVC is something you want to learn then I would pick up already made framework (CodeIngiter, Zend etc) and learn it along with the concepts. This way you learn how to use tools vs. how to forge tools. But, I guess it depends what you are after.
For what is worth…
All the best!