Author: Harry fuecks translation: Easy Chen
The MVC pattern is common in the Web site architecture. It allows us to build a three-tier application, isolate useful layers from code, help designers and developers work together, and improve our ability to maintain and extend existing programs.
Views (view)
"View" mainly refers to the end result we send to the Web browser--such as the HTML generated by our script. When it comes to views, many people think of templates, but the correctness of the template scheme called views is questionable.
The most important thing about the view is that it should be "self aware", and when views are rendered (render), the elements of the view are aware of their role in the larger frame.
In the case of XML, it can be said that when XML is parsed, the DOM API has the knowledge that a node in a DOM tree knows where it is and what it contains. (When a node in an XML document is parsed with sax, it makes sense only if it is resolved to that node.) )
The vast majority of template schemes use simple process languages and such template tags:
<p>{some_text}</p>
<p>{some_more_text}</p>
They don't make sense in the document, they mean only that PHP will replace it with something else.
If you agree with this loosely described view, you will agree that most template schemes do not have a valid separation of views and models. The template label will be replaced with what is stored in the model.
Ask yourself a few questions when you implement the view: Is it easy to replace the whole view? "" How long does it take to implement a new view? Can you easily replace the description language of a view? (such as replacing an HTML document with a SOAP document in the same view) "
Models (model)
The model represents the program logic. (often referred to as the business layer (business layer) in an enterprise-level program)
In general, the task of the model is to convert the original data into data that contains some meaning, which will be displayed by the view. Typically, a model encapsulates a data query, possibly through some abstract data class (data access layer). For example, if you want to calculate the annual rainfall in the UK (just to find yourself a better place to go for a vacation), the model will receive the daily rainfall of the decade, calculate the average, and pass it on to the view.
Controller (Controller)
Simply put, the controller is part of the first invocation of the HTTP request entered in the Web application. It checks for incoming requests, such as some get variables, to make appropriate feedback. Before you write your first controller, it's hard to start writing other PHP code. The most common usage is the structure of a index.php like a switch statement:
<?php
Switch ($_get[' viewpage ']) {
Case "News":
$page =new Newsrenderer;
Break
Case "Links":
$page =new Linksrenderer;
Break
Default
$page =new Homepagerenderer;
Break
}
$page->display ();
?>
This code is mixed with procedures and object-oriented code, but for small sites, this is usually the best choice. Although the above code can also be optimized.
The controller is actually a control that triggers the binding between the data and view elements of the model.
Example
Here is a simple example of using the MVC pattern.
First we need a database access class, which is a generic class.
<?php
/**
* A Simple class for querying MySQL
*/
Class DataAccess {
/**
* Private
* $DB stores a database resource
*/
var $db;
/**
* Private
* $query stores a query resource
*/
var $query; Query Resource
//! A constructor.
/**
* Constucts a new DataAccess object
* @param $host string hostname for DBServer
* @param $user string DBServer user
* @param $pass string dbserver user password
* @param $db String database name
*/
function DataAccess ($host, $user, $pass, $db) {
$this->db=mysql_pconnect ($host, $user, $pass);
mysql_select_db ($db, $this->db);
}
//! An accessor
/**
* Fetches a query and stores it in a
* @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;
}
}
?>
Put the model on top of it.
<?php
/**
* fetches ' products ' from the database
*/
Class ProductModel {
/**
* Private
* $dao An instance of the DataAccess class
*/
var $dao;
//! A constructor.
/**
* Constucts a new ProductModel object
* @param $dbobject An instance of the DataAccess class
*/
Function ProductModel (& $dao) {
$this->dao=& $dao;
}
//! A Manipulator
/**
* tells the $dboject to store this query as a resource
* @param $start the row to start
* @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 the products WHERE productid= '". $id. "");
}
//! A Manipulator
/**
* Fetches a product as a associative array from the $dbobject
* @return Mixed
*/
function GetProduct () {
if ($product = $this->dao->getrow ())
return $product;
Else
return false;
}
}
?>
It is important to note that there is no more than one row between the model and the data access classes--no more rows are being routed, which slows the program down quickly. The same program for classes that use patterns, it only needs to keep one row in memory--others to the saved query resource (query Resource)--in other words, we let MySQL keep the results for us.
Next is the view--I cut out the HTML to save space, and you can view the full code for this article.
<?php
/**
* Binds product data to HTML rendering
*/
Class ProductView {
/**
* Private
* $model An instance of the ProductModel class
*/
var $model;
/**
* Private
* $output rendered HTML is stored this for display
*/
var $output;
//! A constructor.
/**
* Constucts a new ProductView object
* @param $model An instance of the ProductModel class
*/
Function ProductView (& $model) {
$this->model=& $model;
}
//! A Manipulator
/**
* Builds the top of 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;
}
}
?>
Finally, the controller, we will implement the view as a subclass.
<?php
/**
* Controls the application
*/
Class Productcontroller extends ProductView {
//! A constructor.
/**
* Constucts a new Productcontroller object
* @param $model An instance of the ProductModel class
* @param $getvars The incoming HTTP get method variables
*/
Function Productcontroller (& $model, $getvars =null) {
ProductView::P Roductview ($model);
$this->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 ();
}
}
?>
Note that this is not the only way to implement MVC-for example, you can integrate views with the controller implementation model. This is just one way of demonstrating patterns.
Our index.php file looks like this:
<?php
Require_once (' lib/dataaccess.php ');
Require_once (' lib/productmodel.php ');
Require_once (' lib/productview.php ');
Require_once (' lib/productcontroller.php ');
$dao =& new DataAccess (' localhost ', ' user ', ' Pass ', ' dbname ');
$productModel =& New ProductModel ($dao);
$productController =& New Productcontroller ($productModel, $_get);
echo $productController->display ();
?>
Beautiful and simple.
We have some tips for using controllers that you can do in PHP:
$this->{$_get[' method ']} ($_get[' param '));
One suggestion is that you'd better define the name space form (namespace) of the program URL, so that it will compare specifications such as:
"Index.php?class=productview&method=productitem&id=4"
Through it we can handle our controllers like this:
$view =new $_get[' class '];
$view->{$_get[' method '] ($_get[' id '));
Sometimes it's hard to build a controller, such as when you're balancing development speed and adaptability. One good place to get inspiration is the Java Struts of Apache Group, whose controllers are entirely defined by XML documents.