詳解PHP實現(xiàn)MVC的幾種方法
我們這里介紹PHP實現(xiàn)MVC的幾種方法,首先將從什么是MVC,然后以代碼的形式介紹PHP實現(xiàn)MVC。相信所有習(xí)慣了使用MVC來組織自己的項目的人,讓他選擇一個新的項目構(gòu)架時,一定不會放棄MVC。
傳統(tǒng)的面相過程式的開發(fā)方式在處理中型以上的應(yīng)用時,就開始顯得力不從心。即便我們能夠快速的完成需求,但是在需求發(fā)生變更后或者進(jìn)行后期維護(hù)的時候,我們會深深地陷入我們早期搭建的陷阱中。
什么是MVC?
關(guān)于MVC的定義和解釋,可以說多種多樣。我們可以在Wiki或者[2]中找到更為詳盡的解釋,這里我并不打算,也沒有能力進(jìn)行深入的講解,從PHP開發(fā)的角度來講,MVC可以概括為:
視圖(The View):
一說到視圖,我們很多人都會想到模板引擎(諸如Smarty等等)。其實就是各種各樣的輸出,比如說html模板和Javascript文件等。
模塊(The Model)
模塊代表了程序的邏輯,在企業(yè)應(yīng)用中通常稱為業(yè)務(wù)邏輯層。一般來講,這一層完成的工作是把原始的數(shù)據(jù)處理成按照我們設(shè)計的數(shù)據(jù)結(jié)構(gòu)存儲的有意義的數(shù)據(jù)序列,并將這些數(shù)據(jù)交給視圖去處理。通常情況下, 模塊中會利用一個數(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è)計中呢。
為什么用MVC?
MVC最早是用來解決桌面GUI的編程問題,最早的MVC框架應(yīng)該是Sun在1999年提出的Model 2,后來演變成了Struts。MVC帶給人們深刻的印象,但是我們在使用的過程中,卻并沒有認(rèn)真的想過為什么使用MVC。
在傳統(tǒng)的桌面應(yīng)用中,一旦Model中有時間發(fā)生,我們可以主動的讓View界面進(jìn)行刷新,從而展示后臺發(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來組織自己的項目的人,讓他選擇一個新的項目構(gòu)架時,一定不會放棄MVC。
如何PHP實現(xiàn)MVC?
下面是一個超級簡單的MVC結(jié)構(gòu)實現(xiàn),甚至連數(shù)據(jù)源都用了一個內(nèi)置的固定數(shù)組,雖然簡單,但其實眾多的PHP Framework核心實現(xiàn)的思想應(yīng)該和這個是差不多的,只不過一些framework提供了更多的方便開發(fā)者使用的工具,我也想自己來實現(xiàn)一個PHP的框架,目前正在著手策劃中,也希望自己能夠從框架的開發(fā)中學(xué)習(xí)到更多的PHP設(shè)計思想和方法。
P>【編輯推薦】
- 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 "<br />";
- }
- }
- $controller = new Controller();
- $controller->doAction('link_page', 'b');
- $controller->doAction();
- Model.php
- Code
- 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 = "<a href='#'>Link A</a> ";
- $links.= "<a href='#'>Link B</a> ";
- $links.= "<a href='#'>Link C</a> ";
- return $links;
- }
- }
- View.php
- class View {
- public function display($output){
- // ob_start();
- echo $output;
- }
- }