深入淺析用PHP實(shí)現(xiàn)MVC
在PHP中使用MVC越來越流行了,特別是在一些開源的框架當(dāng)中。MVC足以應(yīng)對(duì)大多數(shù)的情況,但還有一些情況是其不太適合的,如比較簡單的個(gè)人博客,對(duì)于只有幾百篇文章量級(jí)的博客,使用MVC讓人覺得有些太復(fù)雜了;同樣對(duì)于新浪等門戶網(wǎng)站,使用MVC,將有大量的文件被加載,對(duì)于速度的影響是無法接受的
傳統(tǒng)的面相過程式的開發(fā)方式在處理中型以上的應(yīng)用時(shí),就開始顯得力不從心。即便我們能夠快速的完成需求,但是在需求發(fā)生變更后或者進(jìn)行后期維護(hù)的時(shí)候,我們會(huì)深深地陷入我們?cè)缙诖罱ǖ南葳逯?。所以,使用面向?qū)ο蟮姆绞絹韺?shí)現(xiàn)MVC模式,將為我們梳理程序的架構(gòu)提供一個(gè)清晰的思路。
什么是MVC?
關(guān)于MVC的定義和解釋,可以說多種多樣。我們可以在Wiki或者[2]中找到更為詳盡的解釋,這里我并不打算,也沒有能力進(jìn)行深入的講解,從PHP開發(fā)的角度來講,MVC可以概括為:
視圖(The View):
一說到視圖,我們很多人都會(huì)想到模板引擎(諸如Smarty等等)。其實(shí)就是各種各樣的輸出,比如說html模板和Javascript文件等。
模塊(The Model)
模塊代表了程序的邏輯,在企業(yè)應(yīng)用中通常稱為業(yè)務(wù)邏輯層。一般來講,這一層完成的工作是把原始的數(shù)據(jù)處理成按照我們?cè)O(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)的有意義的數(shù)據(jù)序列,并將這些數(shù)據(jù)交給視圖去處理。通常情況下, 模塊中會(huì)利用一個(gè)數(shù)據(jù)抽象類來進(jìn)行與數(shù)據(jù)操作有關(guān)的處理。
Model通常包含了哪些用來同數(shù)據(jù)庫打交道的函數(shù)。
控制器(The Controller)
控制器使所有WEB應(yīng)用的第一站,他接受收到的參數(shù),比如$_GET變量,然后做出相應(yīng)的反應(yīng)。
關(guān)于MVC的是否適合PHP的爭論也很多,人們不斷的討論MVC是否適合PHP[3],現(xiàn)在也已經(jīng)有了很多的MVC框架,諸如PHP MVC Frameworks中列出的[4]。那么,為什么人們這么熱衷于MVC,我們?yōu)槭裁匆褂肕VC在我們的設(shè)計(jì)中呢。
為什么用MVC?
MVC最早是用來解決桌面GUI的編程問題,最早的MVC框架應(yīng)該是Sun在1999年提出的Model 2,后來演變成了Struts。MVC帶給人們深刻的印象,但是我們?cè)谑褂玫倪^程中,卻并沒有認(rèn)真的想過為什么使用MVC。
在傳統(tǒng)的桌面應(yīng)用中,一旦Model中有時(shí)間發(fā)生,我們可以主動(dòng)的讓View界面進(jìn)行刷新,從而展示后臺(tái)發(fā)生的變化。而在Web應(yīng)用中,我們似乎限于傳統(tǒng)的 Http的Request/Response的方式,我們似乎沒有辦法讓用戶端進(jìn)行更新。這一段討論,并不是認(rèn)為MVC不能夠用來進(jìn)行WEB應(yīng)用的開發(fā),而是覺得從某種程度上來說,他還不是最合適的。
關(guān)于使用MVC的爭論還有很多[1],但是相信所有習(xí)慣了使用MVC來組織自己的項(xiàng)目的人,讓他選擇一個(gè)新的項(xiàng)目構(gòu)架時(shí),一定不會(huì)放棄MVC。
如何實(shí)現(xiàn)MVC?
下面是一個(gè)超級(jí)簡單的MVC結(jié)構(gòu)實(shí)現(xiàn),甚至連數(shù)據(jù)源都用了一個(gè)內(nèi)置的固定數(shù)組,雖然簡單,但其實(shí)眾多的PHP Framework核心實(shí)現(xiàn)的思想應(yīng)該和這個(gè)是差不多的,只不過一些framework提供了更多的方便開發(fā)者使用的工具,我也想自己來實(shí)現(xiàn)一個(gè)PHP的框架,目前正在著手策劃中,也希望自己能夠從框架的開發(fā)中學(xué)習(xí)到更多的PHP設(shè)計(jì)思想和方法。
Controller.php
include 'Model.php'; include 'View.php'; class Controller { private $model = ''; private $view = ''; public function Controller(){ $this->model = new Model(); $this->view = new View(); } public function doAction( $method = 'defaultMethod', $params = array() ){ if( empty($method) ){ $this->defaultMethod(); }else if( method_exists($this, $method) ){ call_user_func(array($this, $method), $params); }else{ $this->nonexisting_method(); } } public function link_page($name = ''){ $links = $this->model->getLinks(); $this->view->display($links); $result = $this->model->getResult($name); $this->view->display($result); } public function defaultMethod(){ $this->br(); echo "This is the default method. "; } public function nonexisting_method(){ $this->br(); echo "This is the noexisting method. "; } public function br(){ echo ""; } } $controller = new Controller(); $controller->doAction('link_page', 'b'); $controller->doAction(); ================================== Model.php class Model { private $database = array( "a" => "hello world", "b" => "ok well done", "c" => "good bye", ); //@TODO connect the database //run the query and get the result public function getResult($name){ if( empty($name) ){ return FALSE; } if( in_array($name, array_keys( $this->database ) ) ){ return $this->database[$name]; } } public function getLinks(){ $links = "Link A "; $links.= "Link B "; $links.= "Link C "; return $links; } } ==================================================== View.php class View { public function display($output){ // ob_start(); echo $output; } }
相關(guān)文章
PHP實(shí)現(xiàn)頁面靜態(tài)化的超簡單方法
下面小編就為大家?guī)硪黄狿HP實(shí)現(xiàn)頁面靜態(tài)化的超簡單方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09thinkPHP框架實(shí)現(xiàn)圖像裁剪、縮放、加水印的方法
這篇文章主要介紹了thinkPHP框架實(shí)現(xiàn)圖像裁剪、縮放、加水印的方法,結(jié)合實(shí)例形式給出了thinkPHP針對(duì)圖片進(jìn)行裁剪、縮放及加水印的自定義函數(shù),具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03Laravel5.1 框架Request請(qǐng)求操作常見用法實(shí)例分析
這篇文章主要介紹了Laravel5.1 框架Request請(qǐng)求操作常見用法,結(jié)合實(shí)例形式分析了Laravel5.1 框架Request請(qǐng)求操作常見的屬性和方法,及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2020-01-01PHP 閉包獲取外部變量和global關(guān)鍵字聲明變量的區(qū)別講解
閉包是一個(gè)常見的概念,我們通常可以將其與回調(diào)函數(shù)配合使用,可以使代碼更加簡潔易讀。這篇文章主要介紹了PHP 閉包獲取外部變量和global關(guān)鍵字聲明變量的區(qū)別,需要的朋友可以參考下2017-12-12Laravel5.4框架使用socialite實(shí)現(xiàn)github登錄的方法
這篇文章主要介紹了Laravel5.4框架使用socialite實(shí)現(xiàn)github登錄的方法,結(jié)合實(shí)例形式分析了Laravel相關(guān)下載、安裝、配置及github登陸、注冊(cè)、設(shè)置等相關(guān)操作技巧,需要的朋友可以參考下2019-03-03laravel框架select2多選插件初始化默認(rèn)選中項(xiàng)操作示例
這篇文章主要介紹了laravel框架select2多選插件初始化默認(rèn)選中項(xiàng)操作,結(jié)合實(shí)例形式分析了laravel框架select2多選插件的基本初始化、設(shè)置默認(rèn)選中項(xiàng)等相關(guān)操作技巧,需要的朋友可以參考下2020-02-02