The MVC pattern very commonly used in constructing web applications. The principle allows us to construct 3-tier applications, allowing us useful layers of seperation in our code, and helping both designers and developers to cooperate as well enhancing our ability to maintain and expand on existing applications. (({{design:archive:mvc.zip|Sample MCV Code}} )) ======The View====== "Views" are basically the end result which we send to a web browser - the HTML generated by our script, for example. When talking about views, many people think of [[design:templates_and_template_engines|template solutions]] but whether it's accurate to call a template engine a View is debatable. Perhaps the key thing about Views is they should be "self aware", in that as a View is rendered, elements of the view are aware of their role in the greater scheme of things. Taking XML as the example, one might say that XML parsed with the DOM API has this awareness - a node in a dom tree knows where it is and what it contains while nodes in an XML document parsed with SAX have no understanding over themselves until the parser reaches them. Most PHP template solutions use some simplistic procedure language and certainly template tags used like this;

{some_text}

{some_more_text}

Have no understanding of the document they will become, what they represent and are simply there for PHP to replace them with something else. If you agree with this loose description of a View, you'll also agree that most of the template engines fail to create the desired division between View and Model, the knowledge of what the template tags will become having to be stored within the Model. Some questions to ask yourself when implementing Views: "How easy is it to make global changes to all views?", "How long does it take to implement new views?", "Can presentation language delivered by the View be easily interchanged with another (e.g. deliver a SOAP document instead of an HTML document from the same View). ======The Model====== The Model represents application logic (often called the business layer in enterprise applications). Generally speaking, it's the job of the Model to transform raw data into data which contains some sort of meaning, which is then delivered to the View for display. Frequently the Model will encapsulate database queries, perhaps taking advantage of an abstract database class (a data access layer) to actually perform the queries. For example, say you wanted to calculate the yearly rainfall in the United Kingdom (just to convince yourself there's better places for a holiday), the Model would receive a set of daily rainfall figures for ten years then perform an average and deliver it to the View. ======The Controller====== The controller is basically the first point of call for any incoming HTTP requests in a web application. It examines what it received in the request, such as a collection of GET variables, as responds appropiately. You can hardly even begin coding PHP without writing your first controller of some sort. The most common use is something like a switch() statement in your index.php such as; display(); ?> That's using a mix of procedural and object oriented code but for a small website, is frequently a perfectly valid choice. The above code could do better though. The Controller is essentially the component which triggers the binding of data from the Model to elements in the View. ======An Example====== Here's a simple example of the MVC pattern in action. First we need a data access layer, which is generic class; db=mysql_pconnect($host,$user,$pass); mysql_select_db($db,$this->db); } //! An accessor /** * Fetches a query resources and stores it in a local member * @param $sql string the database query to run * @return void */ function fetch($sql) { $this->query=mysql_unbuffered_query($sql,$this->db); // Perform query here } //! An accessor /** * Returns an associative array of a query row * @return mixed */ function getRow () { if ( $row=mysql_fetch_array($this->query,MYSQL_ASSOC) ) return $row; else return false; } } ?> On top of this be place the Model; dao=& $dao; } //! A manipulator /** * Tells the $dboject to store this query as a resource * @param $start the row to start from * @param $rows the number of rows to fetch * @return void */ function listProducts($start=1,$rows=50) { $this->dao->fetch("SELECT * FROM products LIMIT ".$start.", ".$rows); } //! A manipulator /** * Tells the $dboject to store this query as a resource * @param $id a primary key for a row * @return void */ function listProduct($id) { $this->dao->fetch("SELECT * FROM products WHERE PRODUCTID='".$id."'"); } //! A manipulator /** * Fetches a product as an associative array from the $dbobject * @return mixed */ function getProduct() { if ( $product=$this->dao->getRow() ) return $product; else return false; } } ?> One thing to note is between the Model and the data access class, they never exchange more than a single row as an array - there's no passing of multiple rows, which can serious slow an application down. The same applies to the class which uses the Model - it need only ever hold one row in memory - the rest is down to a stored query resource - in other words we leave to MySQL to hold the result for us. Next the View - I've left out the HTML to save space but you'll find it in the complete code for this article. model=& $model; } //! A manipulator /** * Builds the top of an HTML page * @return void */ function header () { } //! A manipulator /** * Builds the bottom of an HTML page * @return void */ function footer () { } //! A manipulator /** * Displays a single product * @return void */ function productItem($id=1) { $this->model->listProduct($id); while ( $product=$this->model->getProduct() ) { // Bind data to HTML } } //! A manipulator /** * Builds a product table * @return void */ function productTable($rownum=1) { $rowsperpage='20'; $this->model->listProducts($rownum,$rowsperpage); while ( $product=$this->model->getProduct() ) { // Bind data to HTML } } //! An accessor /** * Returns the rendered HTML * @return string */ function display () { return $this->output; } } ?> And finally the Controller, which we'll have implement the View as a child; header(); switch ( $getvars['view'] ) { case "product": $this->productItem($getvars['id']); break; default: if ( empty ($getvars['rownum']) ) { $this->productTable(); } else { $this->productTable($getvars['rownum']); } break; } $this->footer(); } } ?> {{design:archive:mvc.gif?200x118}} Note that this is not the only way to relate the classes in an MCV pattern - you might choose to have the controller implement the Model while aggregating the View, for example. This is just one approach which demonstrates the pattern. Our index.php looks like this; display(); ?> Nice and simple. We could have been more cunning with the controller it's worth noting. With PHP you can pull stunts like this; $this->{$_GET['method']}($_GET['param']); What that approach suggests is you need to define your applications URL namespace doing so that it conforms to a standard such as: "index.php?class=ProductView&method=productItem&id=4" Using that we could do the following in our controller; $view=new $_GET['class']; $view->{$_GET['method']($_GET['id']); In some ways, building the controller is the hardest part, when trying to balance rapid development with scalability. A good place to get inspiration is [[http://jakarta.apache.org/struts/userGuide/building_controller.html|Java Struts]] by the Apache group, where your controller is essentially defined by XML documents.