变相怪杰 发表于 2015-2-4 00:20:19

PHP网站制作之MVC形式的PHP完成

不懂的问题有很多高手帮你解决。但不要认为你是新手,就不能帮助别人,比如今天你学会了怎样安装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-2-4 11:54:21

学好程序语言,多些才是王道,写两个小时代码的作用绝对超过看一天书,这个我是深有体会(顺便还能练打字速度)。

活着的死人 发表于 2015-2-9 22:27:58

环境搭建好,当你看见你的浏览器输出“it works\\\\\\\"时你一定是喜悦的。在你解决问题的时候,我强烈建议多读php手册。

若天明 发表于 2015-2-21 20:57:07

对于初学者来说不推荐去拿钱买的。当然如果一个网站你经常去用,而且里面的资料也比较有用,最好还是买个会员比较好,毕竟那些也是别人的工作成果。

乐观 发表于 2015-3-6 21:32:13

建议加几个专业的phper的群,当然啦需要说话的人多,一处一点问题能有人回答你的,当然啦要让人回答你的问题,平时就得躲在里面聊天,大家混熟啦,愿意回答你问题的人自然就多啦。

仓酷云 发表于 2015-3-12 11:58:37

本文当是我的笔记啦,遇到的问题随时填充

莫相离 发表于 2015-3-19 21:51:15

刚开始安装php的时候,我图了个省事,把php的扩展全都打开啦(就是把php.ini 那一片 extension 前面的冒号全去掉啦),这样自然有好处,以后不用再需要什么功能再来打开。

小妖女 发表于 2015-3-22 21:56:53

首先声明:我是一个菜鸟,是一个初学者。学习了一段php后总是感觉自己没有提高,无奈。经过反思我认为我学习过程中存在很多问题,我改变了学习方法后自我感觉有了明显的进步。

蒙在股里 发表于 2015-4-6 05:08:35

Ps:以上纯属原创,如有雷同,纯属巧合

admin 发表于 2015-4-21 20:10:49

曾经犯过一个很低级的错误,我在文件命名的时候用了一个横线\\\\\\\'-\\\\\\\' 号,结果找了好几个小时的错误,事实是命名的时候 是不能用横线 \\\\\\\'-\\\\\\\' 的,应该用的是下划线\\\\\\\'_\\\\\\\' ;

第二个灵魂 发表于 2015-5-10 22:20:41

没接触过框架的人,也不用害怕,其实框架就是一种命名规范及插件,学会一个框架其余的框架都很好上手的。

再见西城 发表于 2015-5-11 00:02:56

至于模板嘛,各位高人一直以来就是争论不休,我一只小菜鸟就不加入战团啦,咱们新手还是多学点东西的好。

小女巫 发表于 2015-5-11 00:13:40

如果你已经到这种程度了,那么你已经可以做我的老师了。其实php也分很多的区域,

因胸联盟 发表于 2015-6-14 07:00:27

当然这种网站的会员费就几十块钱。

金色的骷髅 发表于 2015-6-14 18:53:45

Ps:以上纯属原创,如有雷同,纯属巧合

只想知道 发表于 2015-6-28 22:19:38

使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。

兰色精灵 发表于 2015-7-14 00:03:04

如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了,

变相怪杰 发表于 2015-7-24 04:06:54

因为blog这样的可以让你接触更多要学的知识,可以接触用到类,模板,js ,ajax

透明 发表于 2015-9-26 12:45:21

微软最近出的新字体“微软雅黑”,虽然是挺漂亮的,不过firefox支持的不是很好,所以能少用还是少用的好。
页: [1]
查看完整版本: PHP网站制作之MVC形式的PHP完成