what confused me is tutorials i found online that contradict some discussions around here.
http://www.phppatterns.com/docs/desi...roller_pattern
Code:
<?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 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;
}
}
?>
Code:
<?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 () {
$this->output=<<<EOD
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Our Products </title>
<style>
body { font-size: 13.75px; font-family: verdana }
td { font-size: 13.75px; font-family: verdana }
.title { font-size: 15.75px; font-weight: bold; font-family: verdana }
.heading {
font-size: 13.75px; font-weight: bold;
font-family: verdana; background-color: #f7f8f9 }
.nav { background-color: #f7f8f9 }
</style>
</head>
<body>
<div align="center" class="title">Our Products</div>
EOD;
$this->output.="\n<div align=\"right\"><a href=\"".
$_SERVER['PHP_SELF']."\">Start Over</a></div>\n";
}
//! A manipulator
/**
* Builds the bottom of an HTML page
* @return void
*/
function footer () {
$this->output.="</body>\n</html>";
}
}
class ProductItemView extends ProductView {
/**
* Private
* $productID ID of product to render
*/
var $productID;
//! A constructor.
/**
* Constucts a new ProductView object
* @param $model an instance of the ProductModel class
*/
function ProductItemView (&$model,$productID) {
ProductView::ProductView($model);
$this->productID=$productID;
}
//! A manipulator
/**
* Renders a single product
* @return void
*/
function productItem() {
$this->model->listProduct($this->productID);
while ( $product=$this->model->getProduct() ) {
$this->output.="<p><b>Name</b>:".$product['PRODUCTNAME']."</p>".
"<p><b>Price</b>:".$product['UNITPRICE']."</p>".
"<p><b># In Stock</b>:".$product['UNITSINSTOCK']."</p>";
if ( $product['DISCONTINUED']==1 ) {
$this->output.="<p>This product has been discontinued.</p>";
}
}
}
//! An accessor
/**
* Returns the rendered HTML
* @return string
*/
function display () {
$this->header();
$this->productItem();
$this->footer();
return $this->output;
}
}
class ProductTableView extends ProductView {
/**
* Private
* $rowsperpage number of results per page
*/
var $rowsPerPage;
/**
* Private
* $rownum begin display of rows at this ID
*/
var $rowNum;
//! A constructor.
/**
* Constucts a new ProductView object
* @param $model an instance of the ProductModel class
*/
function ProductTableView (&$model,$rowsPerPage=20,$rowNum=1) {
ProductView::ProductView($model);
$this->rowsPerPage=$rowsPerPage;
$this->rowNum=$rowNum;
}
//! A manipulator
/**
* Renders a product table
* @return void
*/
function productTable() {
$this->model->listProducts($this->rowNum,$this->rowsPerPage);
$this->output.="<table width=\"600\" align=\"center\">\n<tr>\n".
"<td class=\"heading\">Name</td>\n".
"<td class=\"heading\">Price</td>\n</tr>\n";
while ( $product=$this->model->getProduct() ) {
$lastID=$product['PRODUCTID'];
$this->output.="<tr>\n<td><a href=\"".$_SERVER['PHP_SELF'].
"?view=product&id=".$product['PRODUCTID']."\">".
$product['PRODUCTNAME']."</a></td>".
"<td>".$product['UNITPRICE']."</td>\n</tr>\n";
}
$this->output.="<tr class=\"nav\">\n";
if ( $this->rowNum > 0 && $this->rowNum > $this->rowsPerPage ) {
$this->output.="<td><a href=\"".$_SERVER['PHP_SELF'].
"?view=table&rownum=".($this->rowNum-$this->rowsPerPage).
"\"><< Prev</a></td>";
} else {
$this->output.="<td> </td>";
}
if ( $this->rowsPerPage <= ( $lastID - $this->rowNum ) ) {
$this->output.="<td><a href=\"".$_SERVER['PHP_SELF'].
"?view=table&rownum=".($this->rowNum+$this->rowsPerPage).
"\">Next >></a></td>";
} else {
$this->output.="<td> </td>\n";
}
$this->output.="</tr>\n</table>\n";
}
//! An accessor
/**
* Returns the rendered HTML
* @return string
*/
function display () {
$this->header();
$this->productTable();
$this->footer();
return $this->output;
}
}
?>
Code:
<?php
/**
* Controls the application
*/
class ProductController {
var $model;
var $view;
//! 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 (& $dao) {
$this->model=& new ProductModel($dao);
}
}
class ProductItemController extends ProductController {
//! A constructor.
/**
* Constucts a new ProductItemController object
* @param $model an instance of the ProductModel class
* @param $getvars the incoming HTTP GET method variables
*/
function ProductItemController (& $dao,$getvars=null) {
ProductController::ProductController($dao);
$this->view=& new ProductItemView($this->model,$getvars['id']);
}
function & getView () {
return $this->view;
}
}
class ProductTableController extends ProductController {
//! A constructor.
/**
* Constucts a new ProductTableController object
* @param $model an instance of the ProductModel class
* @param $getvars the incoming HTTP GET method variables
*/
function ProductTableController (& $dao,$getvars=null) {
ProductController::ProductController($dao);
if ( !isset ($getvars['rowsperpage']) )
$rowsperpage=20;
if ( !isset ($getvars['rownum']) )
$getvars['rownum']=1;
$this->view=& new ProductTableView($this->model,
$rowsperpage,
$getvars['rownum']);
}
function & getView () {
return $this->view;
}
}
?>
Code:
<?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');
switch ( $_GET['view'] ) {
case "product":
$controller=& new ProductItemController($dao,$_GET);
break;
default:
$controller=& new ProductTableController($dao,$_GET);
break;
}
$view=$controller->getView();
echo ("<pre>" );
// print_r($controller);
echo ("</pre>" );
echo ($view->display());
?>
as you can see, the ProductModel is being instantiated from the controller. As it's listed in advanced resources, i had trusted that this was correct, but what's being said here is the opposite, and that this example has the implementation wrong. the controller is passing the model to the view...??? so if i'm correct in saying that this example has errors in it, then how many others is this possibly confusing?
it just doesn't seem to be a true MVC example. who knows, maybe i'm wrong.
Bookmarks