//! 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; 
} 
} 
?>
有一点要注意的是,在模型和数据访问类之间,它们的交互从不会多于一行——没有多行被传送,那样会很快使程式慢下来。同样的程式对于使用模式的类,它只需要在内存中保留一行(Row)——其他的交给已保存的查询资源(query resource)——换句话说,我们让MYSQL替我们保持结果。
接下来是视图——我去掉了HTML以节省空间,你可以查看这篇文章的完整代码。
<?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 here 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 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; 
} 
} 
?>
最后是控制器,我们将把视图实现为一个子类。
<?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::ProductView($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(); 
} 
} 
?>
注意这不是实现MVC的唯一方式——比如你可以用控制器实现模型同时整合视图。这只是演示模式的一种方法。
我们的index.php 文件看起来像这样:
<?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(); 
?>
漂亮而简单。
我们有一些使用控制器的技巧,在PHP中你可以这样做:
$this->{$_GET['method']}($_GET['param']);
一个建议是你最好定义程序URL的名字空间形式(namespace),那样它会比较规范比如:
"index.php?class=ProductView&method=productItem&id=4"
通过它我们可以这样处理我们的控制器:
$view=new $_GET['class']; 
$view->{$_GET['method']($_GET['id']);
有时候,建立控制器是件很困难的事情,比如当你在开发速度和适应性之间权衡时。一个获得灵感的好去处是Apache group 的Java Struts,它的控制器完全是由XML文档定义的。  
您可能感兴趣的文章:
