日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

MVC模式的PHP實(shí)現(xiàn)

瀏覽:23日期:2024-01-27 16:44:48

作者:Harry Fuecks 翻譯:Easy Chen; MVC模式在網(wǎng)站架構(gòu)中十分常見(jiàn)。它允許我們建立一個(gè)三層結(jié)構(gòu)的應(yīng)用程式,從代碼中分離出有用的層,幫助設(shè)計(jì)師和開(kāi)發(fā)者協(xié)同工作以及提高我們維護(hù)和擴(kuò)展既有程式的能力。

視圖(View)

“視圖”主要指我們送到Web瀏覽器的最終結(jié)果——比如我們的腳本生成的HTML。當(dāng)說(shuō)到視圖時(shí),很多人想到的是模版,但是把模板方案叫做視圖的正確性是值得懷疑的。

對(duì)視圖來(lái)說(shuō),最重要的事情可能是它應(yīng)該是“自我意識(shí)(self aware)”的,視圖被渲染(render)時(shí),視圖的元素能意識(shí)到自己在更大框架中的角色。

以XML為例,可以說(shuō)XML在被解析時(shí),DOM API有著這樣的認(rèn)知——一個(gè)DOM樹(shù)里的節(jié)點(diǎn)知道它在哪里和它包含了什么。 (當(dāng)一個(gè)XML文檔中的節(jié)點(diǎn)用SAX解析時(shí)只有當(dāng)解析到該節(jié)點(diǎn)時(shí)它才有意義。)

絕大多數(shù)模板方案使用簡(jiǎn)單的過(guò)程語(yǔ)言和這樣的模板標(biāo)簽:

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

它們?cè)谖臋n中沒(méi)有意義,它們代表的意義只是PHP將用其他的東西來(lái)替換它。

如果你同意這種對(duì)視圖的松散描述,你也就會(huì)同意絕大多數(shù)模板方案并沒(méi)有有效的分離視圖和模型。模板標(biāo)簽將被替換成什么存放在模型中。

在你實(shí)現(xiàn)視圖時(shí)問(wèn)自己幾個(gè)問(wèn)題:“全體視圖的替換容易嗎?”“實(shí)現(xiàn)一個(gè)新視圖要多久?” “能很容易的替換視圖的描述語(yǔ)言嗎?(比如在同一個(gè)視圖中用SOAP文檔替換HTML文檔)”

模型(Model)

模型代表了程序邏輯。(在企業(yè)級(jí)程序中經(jīng)常稱為業(yè)務(wù)層(business layer))

總的來(lái)說(shuō),模型的任務(wù)是把原有數(shù)據(jù)轉(zhuǎn)換成包含某些意義的數(shù)據(jù),這些數(shù)據(jù)將被視圖所顯示。通常,模型將封裝數(shù)據(jù)查詢,可能通過(guò)一些抽象數(shù)據(jù)類(數(shù)據(jù)訪問(wèn)層)來(lái)實(shí)現(xiàn)查詢。舉例說(shuō),你希望計(jì)算英國(guó)年度降雨量(只是為了給你自己找個(gè)好點(diǎn)的度假地),模型將接收十年中每天的降雨量,計(jì)算出平均值,再傳遞給視圖。

控制器(controller)

簡(jiǎn)單的說(shuō)控制器是Web應(yīng)用中進(jìn)入的HTTP請(qǐng)求最先調(diào)用的一部分。它檢查收到的請(qǐng)求,比如一些GET變量,做出合適的反饋。在寫(xiě)出你的第一個(gè)控制器之前,你很難開(kāi)始編寫(xiě)其他的PHP代碼。最常見(jiàn)的用法是index.php中像switch語(yǔ)句的結(jié)構(gòu):

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

這段代碼混用了面向過(guò)程和對(duì)象的代碼,但是對(duì)于小的站點(diǎn)來(lái)說(shuō),這通常是最好的選擇。雖然上邊的代碼還可以優(yōu)化。

控制器實(shí)際上是用來(lái)觸發(fā)模型的數(shù)據(jù)和視圖元素之間的綁定的控件。

例子

這里是一個(gè)使用MVC模式的簡(jiǎn)單例子。首先我們需要一個(gè)數(shù)據(jù)庫(kù)訪問(wèn)類,它是一個(gè)普通類。

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

有一點(diǎn)要注意的是,在模型和數(shù)據(jù)訪問(wèn)類之間,它們的交互從不會(huì)多于一行——沒(méi)有多行被傳送,那樣會(huì)很快使程式慢下來(lái)。同樣的程式對(duì)于使用模式的類,它只需要在內(nèi)存中保留一行(Row)——其他的交給已保存的查詢資源(query resource)——換句話說(shuō),我們讓MYSQL替我們保持結(jié)果。

接下來(lái)是視圖——我去掉了HTML以節(jié)省空間,你可以查看這篇文章的完整代碼。

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

最后是控制器,我們將把視圖實(shí)現(xiàn)為一個(gè)子類。

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

注意這不是實(shí)現(xiàn)MVC的唯一方式——比如你可以用控制器實(shí)現(xiàn)模型同時(shí)整合視圖。這只是演示模式的一種方法。

我們的index.php 文件看起來(lái)像這樣:

<?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(); ?>

漂亮而簡(jiǎn)單。

我們有一些使用控制器的技巧,在PHP中你可以這樣做:

$this->{$_GET['method']}($_GET['param']);

一個(gè)建議是你最好定義程序URL的名字空間形式(namespace),那樣它會(huì)比較規(guī)范比如:

'index.php?class=ProductView&method=productItem&id=4'

通過(guò)它我們可以這樣處理我們的控制器:

$view=new $_GET['class']; $view->{$_GET['method']($_GET['id']);

有時(shí)候,建立控制器是件很困難的事情,比如當(dāng)你在開(kāi)發(fā)速度和適應(yīng)性之間權(quán)衡時(shí)。一個(gè)獲得靈感的好去處是Apache group 的Java Struts,它的控制器完全是由XML文檔定義的。;

標(biāo)簽: PHP
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品日韩毛片| 麻豆精品久久| 欧美成人精品三级网站| 国产一区2区| 日本一不卡视频| 日韩1区2区3区| 日韩精品第二页| 日韩av网站在线免费观看| 综合一区av| 鲁大师影院一区二区三区| 五月综合激情| 国产手机视频一区二区| 中文精品在线| 日韩午夜av在线| 国产一级一区二区| 天堂俺去俺来也www久久婷婷| 免费一区二区视频| 亚洲精品乱码日韩| 日本aⅴ亚洲精品中文乱码| 久久亚洲风情| 一级成人国产| 日韩毛片一区| 国产亚洲一区| 久久99久久久精品欧美| 国产极品嫩模在线观看91精品| 老鸭窝一区二区久久精品| 国产一区二区色噜噜| 黄色在线观看www| 精品亚洲美女网站| 91精品99| 日韩中文字幕亚洲一区二区va在线| 久久午夜视频| 国产欧美一区| 日韩在线短视频| 99精品视频精品精品视频| 日韩午夜精品| 日韩免费精品| 精品一级视频| 久久久成人网| 91精品一区二区三区综合| 中文日韩在线| 欧美视频久久| 成人一区而且| 日韩视频一区二区三区在线播放免费观看| 六月婷婷一区| 国产视频一区二| 久久男人天堂| 亚洲免费在线| 麻豆精品新av中文字幕| 97国产精品| 视频在线观看一区二区三区| 日韩av字幕| 天堂av在线| 日韩欧美三区| 国产高清不卡| 亚洲三区欧美一区国产二区| 精品一区二区三区的国产在线观看| 91精品观看| 麻豆视频观看网址久久| 欧美精品九九| 精品欧美视频| 蜜臀久久99精品久久久久宅男| 精品三级久久久| 天堂av在线一区| 国产精品久久久久久妇女| 亚洲精品1区| 精品国产欧美日韩| 蜜桃视频在线观看一区| 黄色在线观看www| 日韩高清在线一区| 精品一区在线| 精品少妇av| 日韩精品一级二级| 韩国精品主播一区二区在线观看| 91av一区| 制服诱惑一区二区| 久久久久久自在自线| 婷婷综合国产| 国产亚洲精品自拍| 国产精品久久久久久久久久久久久久久 | 亚洲一区二区三区四区五区午夜| 欧美激情视频一区二区三区免费| 免费观看亚洲| 国产精品啊啊啊| 午夜久久影院| 久久午夜影视| 色综合五月天| 亚洲日本国产| 九九精品调教| 国产亚洲字幕| 亚洲精品系列| 久久久天天操| 久久影视三级福利片| 亚洲欧美日韩视频二区| 欧美精选视频一区二区| 日本欧美一区| 蜜臀av一区二区在线免费观看| 高清精品久久| 国产精品午夜一区二区三区| 国精品一区二区| 精品国产免费人成网站| 欧美亚洲综合视频| 亚洲午夜91| 久久男人天堂| 91精品国产自产精品男人的天堂| 男人的天堂亚洲一区| 日韩深夜视频| 国产a久久精品一区二区三区| 亚洲日本久久| 亚洲天堂av资源在线观看| xxxxx性欧美特大| 国产一区丝袜| 日韩一区精品| 亚洲毛片视频| 午夜久久99| 日本蜜桃在线观看视频| 国产麻豆一区二区三区精品视频| 国产网站在线| 国产精品久久久久77777丨| 天堂av在线一区| 蜜臀91精品一区二区三区| 国户精品久久久久久久久久久不卡| 999精品在线| 亚洲精品福利电影| 日韩免费视频| 国产一区一一区高清不卡| 精品国产精品国产偷麻豆| 久久精品凹凸全集| 国产精品夜夜夜| 日韩三级视频| 久久国产精品免费精品3p| 亚洲色图综合| 欧美视频久久| 日韩中文字幕在线一区| 香蕉久久一区| 日精品一区二区三区| 天使萌一区二区三区免费观看| 亚洲第一区色| 日韩综合一区二区| **爰片久久毛片| 日本不卡一二三区黄网| 久久国产人妖系列| 精品丝袜久久| 亚洲天堂一区二区| 日韩毛片视频| 国产精品7m凸凹视频分类| 久久在线免费| 亚洲免费网址| 亚洲精品a级片| 亚洲欧洲专区| 亚洲精品成人一区| 国产极品久久久久久久久波多结野| 欧美亚洲tv| 国产videos久久| 欧美男人天堂| 国产视频亚洲| 亚洲日本在线观看视频| 日韩二区三区四区| 国产精品最新| 亚洲精品一级二级| 免费欧美一区| 99视频精品| 亚洲人亚洲人色久| 中文字幕av一区二区三区人| 亚洲精品自拍| 国产精品亚洲片在线播放| 久久精品国产在热久久| 国产在线观看www| 在线亚洲国产精品网站| 亚洲男女av一区二区| 亚洲精品九九| 国产欧美88| 成人久久一区| 亚洲精品中文字幕乱码| 日韩av中文字幕一区二区三区| 国产欧美日韩影院| 秋霞影视一区二区三区| 91久久久精品国产| 午夜天堂精品久久久久| 亚洲视频国产| 国产精品高颜值在线观看| 激情久久五月| 国产精品亚洲二区| 日韩欧美精品| 日韩高清在线观看一区二区| 国产精品亚洲欧美| 亚洲国产专区| 一区二区三区四区精品视频| 成人午夜亚洲| 亚洲成人免费| 国产欧美大片| 精精国产xxxx视频在线野外| 亚洲1区在线| 麻豆国产精品777777在线| 欧美不卡高清| 国产亚洲精品精品国产亚洲综合| 波多野结衣一区| 国产日韩欧美一区二区三区| 亚洲精品小说| 国产精品嫩草99av在线|