MVC:: Which goes where? - php

I was a flat php programmer for past 2 years. Now I want to move to MVC architecture and so I am using codeigniter which looks very simple to start with. I want to know some of the best practices out there as I go developing in codeigniter.
I have a controller called building, a model called building_data and a view called building_view. Now i want to display list of building by checking lot of conditions. I am doing the following in flat PHP
Get the list of buildings from database
Split the result based on certain criteria A, B, C
Display the result in section - A, section -B, and section-c as the HTML output.
Now in MVC I am doing the following
Get the list of building in the database on building_data (model)
Store the result from building_data in a $data array of the building controller
Split the results based on criteria A,B,C in building_view and output the HTML (can i do the condition based classification of data (without using mysql queries) in view ? !My actual question)
Am I doing the right thing here without violating MVC architecture rules ?

MVC is a design pattern. Not an architecture.
But, if you are looking to learn best practices or MVC, then CodeIgniter is the wrong choice. It is filled with bad and outdated practices (PHP4 code fragments, global state and many other issues), and is not implementing anything even close to MVC pattern. It is more like a bad Rails clone for PHP.
Views are supposed to be objects, and not dumb templates. Your controller should tell model layer which building the user has selected, and then view acquires the details about current building and decides how to represent it all.
In proper MVC implementation, views are instances which contain presentation logic. They acquire information from model layer and then choose which templates to use for rendering the response or even if a HTML response is necessary. Maybe user actually requested data in JSON or XML format. Or maybe the only response, that view needs to send, is a HTTP header.
Also you should be aware that you cannot implement classical MVC pattern in web application (or at least it is extremely difficult and entails use of sockets and persistent model). Instead we use MVC-inspired patterns. The main difference between them is way how View gets to the information from Model layer.
in MVP and MVVM patterns the view is passive and receives data through controller-like structure (presenters or viewmodel, perspectively).
in Model2 MVC and HMVC patterns the view is active, it requests information directly from model layer.
Also there is third group: Rails-like implementation. It replaces model layer with collection of ActiveRecord based ORMs, pretend that view is a template, and "controller" is combination of presenter and view responsibilities.

Related

Simple model layer for a small website with tiny logic

I have struggled with an MVC concept for a long time in php since I'm not a php developer. I refactored my site several times but it still looks like a cannon pointed in a mosquito. I've read many articles, posts and answears about MVC but it still makes me confused.
Let's have a simple website with articles and comments system. Everything is stored directly in a database (information about articles, paths, comments etc.). Mostly based on this I developed my own app using MVC. Here is how it works:
Controller retrieves data from the database about an article and related comments
It creates required model's objects (current article and comments)
... and then passes necessary data to the View
View presents those data by applying particular templates for provided objects
Everything works like a charm but...
my model's objects don't need any external logic so my domain objects are bordered to getter/setter classes -I'm wondering: do I need domain objects? It's pointless to store separated objects only for getting them from DB and displaying on a website after a while, isn't it?
controller holds a DB connection passed to services and mappers for creating a model's object -but queries stored in mappers can be merged into services functionality
In conclusion, I wonder if it's not a better approach to replace three-part model with a single manager (per object) which will retrieve all necessary data from the database and will pass them in any way and form (i.e. associative array) to the View.
Please do note, that I'm describing a simple case (1:1:1) with tiny logic, where most data retrieved from database are only for a presentation purpose.
Well what you have just described is an architectural pattern for data modelling called the Data Mapper pattern.
In this pattern you separate the persistence logic to a Mapper class and leave all of the Data stuff in The Domain Model. In your scenario you mentioned there is little logic, which is fine. Logic grows as your application matures. The key point is the separation, persistence has nothing to do with logic and therefore should be moved into a different class.
The Mapper class is only concerned with persisting data (generally to whatever data store you choose), in practice you uses "Adapters", which is why in some ORMs you see a different adapter for different data stores (ie. MySQLAdapater vs PostGresAdapater... etc, implementing a abstract Adapter Interface/Base Class).
It should be noted though, in your conclusion what you describe is actually the MVC Architecture.
The Model Layer is essentially your Persistence Layer (like described above)
The View Layer is where you present your data.
Your Controller Layer is where your data manipulation ie On your domain object's data.
Typically a MVC request goes like...
a URI gets mapped to a controller::action
Action gets data, manipulates it and sends it to the view for rendering.
When MVC applications run into trouble is when your Controller accesses several different objects and needs to persist them all. The class architecture of an MVC application tends to be very heavy as the Models typically have more logic on them than in the Data Mapper pattern since MVC models have persistence tied into them (in practice).
Just as an aside, for simple projects like yours, you might want to look into simple presentation frameworks like http://www.slimframework.com/ It has no persistence layer built in, which leaves you to choose the best for your project.

Basic MVC (PHP) Structure

I have the following data flow for a simple login form.
User access controller PHP file. Controller includes model.php and view.php
User submits form, controller sends POST data to model methods, and gets a result back.
User is logged in, and forwarded to a different view (login success message) by the controller.
Currently my views are static HTML (no PHP), so here is my question. What is the correct way to then pass the user a welcome message, e.g "Hello, Craig!"?
Is the view allowed PHP snippets, e.g
<?php echo $username; ?>
since the model is loaded before it in the controller file?
Thanks!
Edit: Is it better practice then to allow the view to access specific class methods e.g
<?php $user->getUsername(); ?>
as opposed to just variables?
Based on other answers, I have found a very useful article, which you may also be interested in.
http://www.nathandavison.com/posts/view/7/custom-php-mvc-tutorial-part-5-views
Here are few things you must consider:
You cannot do classical MVC in PHP. Instead we have MVC-inspired patterns
There exists 1:1 relation between view and controller instances, when implemented for web
Model in MVC is not a class. It is a layer, that contains a lot of different classes
View is not a dumb template, but an instance of class, which deals with presentation logic
View in Web-based MVC
As stated above, views in MVC and MVC-inspired patterns are responsible for presentation logic. That encompass things like showing error messages and pagination. To do this, each view can handle several templates.
View receives information from the model layer, and acts accordingly. The way how the information from model layer ends up in views is one of most significant differences in MVC-ish patterns:
classical MVC pattern
Structures from model layer send the information to view, when state of model has been altered. This is done via observer pattern.
Model2 MVC and HMVC patterns
View has direct access to the model layer and is able to request information from it. This is the closest to the original pattern.
MVVM and MVP patterns
View receives information through controller, which has in turn requested it from model layer. The further difference in patterns stems from what the do with data before passing it to view.
What you seem to have now is actually just a template. Similar to one, that is described in this article. You end up with a structure, that has no place to contain the presentation logic. In long-run this will cause the presentation logic to be pushed into controller.
So what about that "welcome" message ?
To show the welcome message, your view should request from model layer the name of current user. If the model layer returns some sort of error state, view pick the error message template and inserts into the layout.
In case if name of the user was retrieved from model layer without problems, view pick the template which would contain the greeting, sets the value in the template and renders it.
In what order parts should be loaded ?
The idea, that controller should initialize model and view, comes from very primitive interpretation of MVC for web. Pattern know as page controller, which tried to graft MVC directly on static web pages.
In my opinion, this should be the order:
Model
You initialize the structure, through which you will deal with model layer. It most likely would be some sort of service factory, which would let you build things like Authentication service for logins and Library service for handling documents. Things like that. I wrote a bit long'ish comment on model layer's structure earlier. You might find it useful.
View
You create a view instance based on information, that you collected from routing mechanism. If you are implementing Model2 or HMVC, then your view will require an instance of Service Factory in the constructor.
If you are implementing MVVM or MVP, then view's constructor has no special requirements.
Controller
This is the last structure, which you create, because controller is responsible for sending commands to both view and model layer, which then change then change the state of both. Therefore controller should expect to receive both view and service factory in the constructor.
After basic elements of MVC have been initialized, you call a method on the controller, and render current view.
Just keep in mind that this is very simplified description.
You can really put anything in a view that you'd like, but to better adhere to the MVC way of doing things you should restrict PHP in the view to simple echos or prints (possibly really small loops as well, although even those can be pre-calculated in the controller/model). Since that is the only way to get dynamic content, it would be a little silly to say that they are not allowed.
The idea of the view is to let it have a more HTML look-and-feel, so that front-end developers or people who don't know PHP can easily be able to work with the file without getting confused.
Update
To learn more about MVC in general, you can see any of these (there's a ton of tutorials out there):
http://blog.iandavis.com/2008/12/09/what-are-the-benefits-of-mvc/
http://php-html.net/tutorials/model-view-controller-in-php/
http://www.tonymarston.net/php-mysql/model-view-controller.html
To see concrete examples of PHP using MVC, I suggest downloading some of the more prevelant frameworks (such as CodeIgniter, Symfony or Drupal) and just looking through the code. Try to figure out how it works and then recreate the functionality for a simple article-based system.

Is this business logic or views in MVC?

Newbie question about MVC structures here. So in an MVC, I currently have a page in my Views to display a list of results from a database query, in this bit of code I instantiate a class, run a method for sql query, and at last there's a for each loop and then displaying it with divs.
So my question is, if this bit of code is considered business logic and should be in a method in the Model, or is it part of the Views?
I hope you understand what I mean =) Thanks!
$listholder = new Categories_Model();
$data = $listholder->getCategories();
$i = 1;
foreach ($data as $row) {
if ($i & 1) {
echo '<div id="horizontalContainer" style="float: none; height: 50px";>';
echo '<div id="listoverview1">'.$row['catname'].'';
echo '</div>';
} else {
echo '<div id="listoverview1">'.$row['catname'].'';
echo '</div></div>';
}
$i++;
}
No, that code is mainly view code. It only purpose is to allow an external process (a human) to see data in a form it likes. Assuming that the check for the first row is only important to the external process, not to your business logic
Model code shapes, gets, and sets data, some of which is persisted (database etc.) and some of which is calculated on demand
Some generalised, and simplified examples on things a model or view should do:
Model calculates the total of some financial figures
View flags each even numbered row so it can be rendered with a shaded background in the view
Also, in a classical MVC system, your first two lines of code would be in the controller, which would organise the dataset by using models and model methods to get data. The MVC system would then pass that data to the selected view to render
There are plenty of PHP based MVC frameworks like CAKE, KISS etc (not all are very good!). If you have a few dollars in your pocket, save yourself some time and stress, and load up Microsoft MVC
From your question you might have some understanding of MVC that has nothing to do with what other developer think what MVC is. That can happen, especially nowadays as some frameworks have used these three letters as a catchphrase without providing it actually.
From the code you outline in your question I'd say it is a typical Transaction Script and there is no specific kind of model nor view layer involved.
The transaction script transports business logic and you do not need to speculate a lot about view or models, just keep everything inside the transaction script.
Your transaction scripts will tend to become spaghetti code, however, with some little refactorings here and there over time you should be able to reduce duplicate code and I do not think your application will grow that large that it is actually not feasible any longer keep it maintained in transaction scripts.
So why being concerned about MVC if everything is in order with some other, well proven pattern?
Taking as an example Rails or CakePHP, your code doesn't follow the mvc pattern.
Model should only contain business logic (query/do something with fields of an object)
Controller should work "only" with receiving requests of webpage with params and send back the correct page
View Is basically an html page only
Obviusly this is a very short briefing of what html is.
In your case, the idea would be:
$listholder = new Categories_Model();
$data = $listholder->getCategories();
Which is a controller code (usually), getCategories is a Model method (ok as is).
Then the controller will send some parameters to view which will know how to display those to the user, in this case your $data variable.
Imagine something like printMyView($view_file_path, $data)
The view will be something like this:
categories/show/">';
categories/show/">';
See http://php.net/manual/en/control-structures.alternative-syntax.php for alternative control structure syntax (quite nice). Maybe URLS are written better with sprintf or things like that (not how I did).
Basically you need 3 files (to split things logically), and the law is quite easy: don't write ever html in Controller, nor in Model.
The goal of MVC design pattern is to separate the presentation from the domain business logic. For that reason the business logic stays exclusively in model layer (model is a layer not any single class, if you have a class named Model, you are doing it wrong), whole the presentation layer contains views an controllers.
Controller instances are one that deal with user's requests, and change the state of model an view instances.
The view instances are the ones, that contain the presentation logic (just like domain objects contain the business logic in model layer). Views acquire information from model layer and decide, which templates will be used, or even whether template is even necessary. Views generate the response in your web site, and sending of redirect header is form of response too, which does not require any templates at all.
Also, you have to understand, that it is impossible to use classical MVC pattern with PHP (and highly complicated and impractical in the few web development, that would provide such option). Instead you would be using one of the MVC-inspired patterns.
These patterns are mostly distinguishable by how* view acquires information from model layer. The main options are: Model2 MVC, MVP, MVVM and HMVC.
In your case, the view should acquire the set of categories from model layer and then, if list is not empty and no exceptions were thrown, select a template which generates an unsorted HTML list.
The business logic would stay in the the model layer (in the domain object, which deals with categories), the presentation logic in the view and the process of turning it all in HTML - in the template, which view picked.

MVC models in PHP - Correct process order and separation

I need help clarifying the correct structure and process flow for an MVC application in PHP.
I think I've got the concept round the wrong way because currently most of my processing is done (or at least initiated by) the Views. -- I kind of inherited this way of thinking from the company I'm working for, but now I'm not sure that they are understanding the MVC model correctly!
Having looked at it again I think that the proccess should be as follows (very basicly):
The users actions are sent to the Controller
The Controller process those actions using any Models required
The Controller then instantiates the relevent View and passes the required data to it
The View renders the page to the user
I'm also having some difficulty deciding wether the view should even have any real functionality in it or not.
i.e. Is it just a wrapper to hold the page data and load the required template files (header, page, footer etc.), OR should any functions to do with rendering data (i.e. preparing HTML and outputting HTML) be in the View?
Another question is does the controller 'hand over' to the model and have nothing to do with the actual DBconn (so that the Model acts like a Bouncer on the doors of the DB nightclub, and we're not on the list) OR does the controller 'own' the DBconn and simply lends it to a model when it needs it?
I'd really appreciate any help and advice anyone can offer.
Thanks
edit -- I found this helpful!
I'll answyer to your two last questions:
1) The Views should have basic output capabilities, for example escaping values to avoid security issues or display a html table starting from a list of objects. Another responsibility could be the translation of labels and other constant values (for example you could have $this->_('Your label') where function _($val) is a function included in all your view classes that translates the strings starting from a csv file).
2) Depending on the complexity application, you could have two sub-layers in the model layer. The upper layer is the classic model with the functionality of your entities. The lower level is the resource model class associated that performs the db operations. You could also have a single layer with your models that implements the DAO pattern. Anyway, the controller shouldn't have nothing to do with db connection.
Your bulleted assumptions are correct :). The main idea behind MVC is loose-coupling and interchangeability between components.
To answer your questions:
The view should be presentational only, so iterating through a list of models in the view and outputting them there is fine, but processing data in the view is not.
The model should not assume anything about the controller and the view. It should be easy for you to switch between a model that draws data from a database to one that draws data from another type of data source and this should not determine changes in the Controller. Fabrizio is right, you should check out the DAO pattern for an example on how to do this.
I really recommend taking a look at frameworks that implement MVC to see how they do it. Especially Spring - even if you're not a Java person, the implementation is very clean -, Rails, Symfony. For something more exotic take a look at Django.

What is MVC, in relation to the Zend framework?

I'm learning the Zend Framework and it uses a MVC model.
I still have not got my head around what MVC Model, View, Controller is.
What are the three different areas for and what would the program flow look like?
M - Models - are often the biggest source of confusion. These are the parts of your application that do all the 'heavy lifting' - they handle database access, perform the complex application-specific logic and are responsible for most of what your application 'does'. Unlike Views and Controllers, the Zend Framework doesn't have a base class for Models - this is because there's no real consistency in what they do. Some frameworks (like Ruby on Rails) try to present some sort of database-wrapper as a base for Model, but there are many cases (3rd party feed/API, static files, non-persistent calculations, concepts that span multiple tables...) for which this is, at best, a misleading practice. The Model is the part of the application where you're still forced to program and the framework can't really save you from it.
V - Views - are the simplest components here. They should be simple PHP/HTML templates. They're given view objects, arrays, strings, etc. which they then put into a page. There shouldn't be much (if any) complex logic here - loop over these, display this (if defined), zebra stripe this table and whatnot. There's some magic happening with View Helpers (such as the helper that magically renders a Zend_Form), but that's not essential to understanding the overall system.
C - Controllers - In the broadest sense, the controller is responsible for taking user requests, sending them off to Model objects and preparing Models to be handed to the Views. It's the glue that holds everything together. If you're using Zend MVC, you're concerned with 2 controllers - Zend_Controller_Front and Zend_Controller_Action.
Zend_Controller_Front (which you get 'for free' if you use Zend_Layout::startMVC()) is a single point of entry for your application - it handles the raw user requests and translates URLs into an Action to call. There are various places to 'plug-in' to this to handle things like authentication and access restrictions, but, at the core it's just the 'traffic cop' at the front gate directing incoming requests.
Zend_Controller_Action is the base class for actions - essentially an Action represents something your application does (log in, list blog entries, launch an ICBM, order a pizza...), but is not directly responsible for actually doing it. The Action Controllers are pretty boring - they pull values out of forms and URLs, call a few methods on Model classes to actually perform the action and push the results out into the view. As has been said before, they're the 'glue' that holds Models and Views together.
A rough test to see if you're splitting things along the right lines is to envision a major change to your site. A visual redesign would almost entirely be handled in the Views. Moving all your URLs would change your Controllers. Converting from a web app to a GUI app would replace the views and controllers, but your model would still be mostly unchanged. If you rewrite your models, you have a whole new application.
There are several other questions on Stackoverflow that give an explanation of the MVC concept:
What are MVP and MVC and what is the difference?
What is MVC (Model View Controller)?
A very good explanation of the concept can be found on Wikipedia:
Model-view-controller (MVC) is an
architectural pattern used in software
engineering. Successful use of the
pattern isolates business logic from
user interface considerations,
resulting in an application where it
is easier to modify either the visual
appearance of the application or the
underlying business rules without
affecting the other. In MVC, the model
represents the information (the data)
of the application; the view
corresponds to elements of the user
interface such as text, checkbox
items, and so forth; and the
controller manages the communication
of data and the business rules used to
manipulate the data to and from the
model.
In relation to Zend Framework:
models are generally presented by extensions of the Zend_Db_Table class
views are presented as *.phtml files in your defined scripts folder, which are handled by the Zend_View class.
controllers are defined by extensions of the Zend_Controller_Action class.
The Zend Framework has its own very nice Quick Start/Tutorial which especially introduces MVC.
Quote from there:
So what exactly is this MVC pattern
everyone keeps talking about, and why
should you care? MVC is much more than
just a three-letter acronym (TLA) that
you can whip out anytime you want to
sound smart; it has become something
of a standard in the design of modern
web applications. And for good reason.
Most web application code falls under
one of the following three categories:
presentation, business logic, and data
access. The MVC pattern models this
separation of concerns well. The end
result is that your presentation code
can be consolidated in one part of
your application with your business
logic in another and your data access
code in yet another. Many developers
have found this well-defined
separation indispensable for keeping
their code organized, especially when
more than one developer is working on
the same application.
In as few words as possible:
model is the db
view is what you see (the page)
controller is the glue (logic)
Your models know how to access tables containing your data; your views know how to display content; and your controllers glue it together (what view do I show? what model should I use?).

Categories