仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2166|回复: 18
打印 上一主题 下一主题

[学习教程] PHP网站制作之MVC形式的PHP完成

[复制链接]
变相怪杰 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-2-4 00:20:19 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
不懂的问题有很多高手帮你解决。但不要认为你是新手,就不能帮助别人,比如今天你学会了怎样安装PHP,明天还可能有朋友会问这个问题,你就可以给他解答,不要认为这是浪费时间,忙别人其实就是帮助自己。   MVC形式在网站架构中非常罕见。它答应咱们创立一个三层布局的使用程式,从代码平分离出有效的层,匡助设计师和开辟者协同任务和进步咱们保护和扩大既有程式的才能。

视图(View)

“视图”次要指咱们送到Web阅读器的终究了局――好比咱们的剧本生成的HTML。当说到视图时,良多人想到的是模版,然而把模板计划叫做视图的准确性是值得嫌疑的。

对视图来讲,最主要的工作多是它应当是“自我认识(self aware)”的,视图被衬着(render)时,视图的元素能意想到本人在更大框架中的脚色。

以XML为例,可以说XML在被解析时,DOM API有着如许的认知――一个DOM树里的节点晓得它在哪里和它包括了甚么。 (当一个XML文档中的节点用SAX解析时只要当解析到该节点时它才成心义。)

绝大多半模板计划利用复杂的进程言语和如许的模板标签:

<p>{some_text}</p>
<p>{some_more_text}</p>


它们在文档中没成心义,它们代表的意义只是PHP将用其他的器材来交换它。

假如你赞同这类对视图的松懈描写,你也就会赞同绝大多半模板计划并没有无效的分别视图和模子。模板标签将被交换成甚么寄存在模子中。

在你完成视图时问本人几个成绩:“全部视图的交换轻易吗?”“完成一个新视图要多久?” “能很轻易的交换视图的描写言语吗?(好比在统一个视图顶用SOAP文档交换HTML文档)”


模子(Model)

模子代表了法式逻辑。(在企业级法式中常常称为营业层(business layer))

总的来讲,模子的义务是把原无数据转换成包括某些意义的数据,这些数据将被视图所显示。凡是,模子将封装数据查询,能够经由过程一些笼统数据类(数据会见层)来完成查询。举例说,你但愿盘算英国年度降雨量(只是为了给你本人找个好点的度假地),模子将吸收十年中天天的降雨量,盘算出均匀值,再传递给视图。


掌握器(controller)

复杂的说掌握器是Web使用中进入的HTTP恳求最早挪用的一局部。它反省收到的恳求,好比一些GET变量,做出适合的反应。在写出你的第一个掌握器之前,你很难入手下手编写其他的PHP代码。最多见的用法是index.php中像switch语句的布局:

<?php
switch ($_GET['viewpage']) {
case "news":
$page=new NewsRenderer;
break;
case "links":
$page=new LinksRenderer;
break;
default:
$page=new HomePageRenderer;
break;
}
$page->display();
?>


这段代码混用了面向进程和对象的代码,然而关于小的站点来讲,这凡是是最好的选择。固然上边的代码还可以优化。

掌握器实践上是用来触发模子的数据和视图元素之间的绑定的控件。


例子

这里是一个利用MVC形式的复杂例子。
起首咱们需求一个数据库会见类,它是一个通俗类。

<?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 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;
}
}
?>


在它上边放上模子。

<?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;
}
}
?>


有一点要注重的是,在模子和数据会见类之间,它们的交互从不会多于一行――没有多行被传送,那样会很快使程式慢上去。一样的程式关于利用形式的类,它只需求在内存中保存一行(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文档界说的。
  也许您在学习PHP的时候只想尽快的开发一个网站,也就会想我做网站,干嘛要学什么网页这些小儿科?不难看出,眼高手低的新手不在少数,这种思想无疑于建造空中楼阁,你不建地基,何来的房顶呢?
变相怪杰 该用户已被删除
沙发
 楼主| 发表于 2015-7-24 04:06:54 | 显示全部楼层
因为blog这样的可以让你接触更多要学的知识,可以接触用到类,模板,js ,ajax
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-5-22 02:43

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表