电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

MVC模式的PHP實現

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

作者:Harry Fuecks 翻譯:Easy Chen; 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
主站蜘蛛池模板: 山东风淋室_201/304不锈钢风淋室净化设备厂家-盛之源风淋室厂家 翻斗式矿车|固定式矿车|曲轨侧卸式矿车|梭式矿车|矿车配件-山东卓力矿车生产厂家 | 厦门ISO认证|厦门ISO9001认证|厦门ISO14001认证|厦门ISO45001认证-艾索咨询专注ISO认证行业 | 杭州月嫂技术培训服务公司-催乳师培训中心报名费用-产后康复师培训机构-杭州优贝姆健康管理有限公司 | MTK核心板|MTK开发板|MTK模块|4G核心板|4G模块|5G核心板|5G模块|安卓核心板|安卓模块|高通核心板-深圳市新移科技有限公司 | 三效蒸发器_多效蒸发器价格_四效三效蒸发器厂家-青岛康景辉 | 可程式恒温恒湿试验箱|恒温恒湿箱|恒温恒湿试验箱|恒温恒湿老化试验箱|高低温试验箱价格报价-广东德瑞检测设备有限公司 | 阻垢剂-反渗透缓蚀阻垢剂厂家-山东鲁东环保科技有限公司 | 环氧乙烷灭菌器_压力蒸汽灭菌器_低温等离子过氧化氢灭菌器 _低温蒸汽甲醛灭菌器_清洗工作站_医用干燥柜_灭菌耗材-环氧乙烷灭菌器_脉动真空压力蒸汽灭菌器_低温等离子灭菌设备_河南省三强医疗器械有限责任公司 | 氟氨基酮、氯硝柳胺、2-氟苯甲酸、异香兰素-新晨化工 | 余姚生活网_余姚论坛_余姚市综合门户网站 | 阿尔法-MDR2000无转子硫化仪-STM566 SATRA拉力试验机-青岛阿尔法仪器有限公司 | 山东PE给水管厂家,山东双壁波纹管,山东钢带增强波纹管,山东PE穿线管,山东PE农田灌溉管,山东MPP电力保护套管-山东德诺塑业有限公司 | 在线浊度仪_悬浮物污泥浓度计_超声波泥位计_污泥界面仪_泥水界面仪-无锡蓝拓仪表科技有限公司 | 全自动实验室洗瓶机,移液管|培养皿|进样瓶清洗机,清洗剂-广州摩特伟希尔机械设备有限责任公司 | 胜为光纤光缆_光纤跳线_单模尾纤_光纤收发器_ODF光纤配线架厂家直销_北京睿创胜为科技有限公司 - 北京睿创胜为科技有限公司 | 济南菜鸟驿站广告|青岛快递车车体|社区媒体-抖音|墙体广告-山东揽胜广告传媒有限公司 | 金属清洗剂,防锈油,切削液,磨削液-青岛朗力防锈材料有限公司 | 安德建奇火花机-阿奇夏米尔慢走丝|高维|发那科-北京杰森柏汇 | 葡萄酒灌装机-食用油灌装机-液体肥灌装设备厂家_青州惠联灌装机械 | 有源电力滤波装置-电力有源滤波器-低压穿排电流互感器|安科瑞 | 双舌接地线-PC68数字式高阻计-ZC36|苏海百科 | 武汉刮刮奖_刮刮卡印刷厂_为企业提供门票印刷_武汉合格证印刷_现金劵代金券印刷制作 - 武汉泽雅印刷有限公司 | 爱佩恒温恒湿测试箱|高低温实验箱|高低温冲击试验箱|冷热冲击试验箱-您身边的模拟环境试验设备技术专家-合作热线:400-6727-800-广东爱佩试验设备有限公司 | 数控专用机床,专用机床,自动线,组合机床,动力头,自动化加工生产线,江苏海鑫机床有限公司 | 台湾阳明固态继电器-奥托尼克斯光电传感器-接近开关-温控器-光纤传感器-编码器一级代理商江苏用之宜电气 | 浙江美尔凯特智能厨卫股份有限公司 | 东莞市海宝机械有限公司-不锈钢分选机-硅胶橡胶-生活垃圾-涡电流-静电-金属-矿石分选机 | 湖南印刷厂|长沙印刷公司|画册印刷|挂历印刷|台历印刷|杂志印刷-乐成印刷 | PVC地板|PVC塑胶地板|PVC地板厂家|地板胶|防静电地板-无锡腾方装饰材料有限公司-咨询热线:4008-798-128 | 赛尔特智能移动阳光房-阳光房厂家-赛尔特建筑科技(广东)有限公司 | 美国HASKEL增压泵-伊莱科elettrotec流量开关-上海方未机械设备有限公司 | 压装机-卧式轴承轮轴数控伺服压装机厂家[铭泽机械] | China plate rolling machine manufacturer,cone rolling machine-Saint Fighter | 洗瓶机厂家-酒瓶玻璃瓶冲瓶机-瓶子烘干机-封口旋盖压盖打塞机_青州惠联灌装机械 | 制丸机,小型中药制丸机,全自动制丸机价格-甘肃恒跃制药设备有限公司 | Brotu | 关注AI,Web3.0,VR/AR,GPT,元宇宙区块链数字产业 | 污水/卧式/潜水/钻井/矿用/大型/小型/泥浆泵,价格,参数,型号,厂家 - 安平县鼎千泵业制造厂 | 深圳市源和塑胶电子有限公司-首页 | 天空彩票天下彩,天空彩天空彩票免费资料,天空彩票与你同行开奖,天下彩正版资料大全 | AGV无人叉车_激光叉车AGV_仓储AGV小车_AGV无人搬运车-南昌IKV机器人有限公司[官网] | 万濠影像仪(万濠投影仪)百科-苏州林泽仪器 |