開發自各兒PHP MVC架構(一)

來源:互聯網
上載者:User
開發自己PHP MVC架構(一)

本教程翻譯自John Squibb 的Build a PHP MVC Framework in an Hour,但有所改動,原文地址:http://johnsquibb.com/tutorials

這個教程可以使大家掌握用mvc模式開發php應用的基本概念。此教程分為三個部分,現在這篇是第一部分。

現在市面上有很多流行的架構供大家使用,但是我們也可以自己動手開發一個mvc架構,採用mvc模式可以大大減少我們開發應用的時間,並且能夠更好的組織項目原始碼,而且其中的某些模組還可在其它項目中使用。現在我要教大家寫一個簡單的mvc架構。由於這個項目很簡單,輕量,所以可能並不是最佳實務,也不具備安全性,還需要大家在實際應用中完善。

所用技術:php,物件導向開發方法。

開始

首先在網站根目錄下建立三個檔案夾

  • models
  • views
  • controllers

然後在根目錄下建立一個檔案:

  • index.php

現在項目結構應該像這樣

§ 網站根目錄

§ index.php

§ models/

§ views/

§ controllers/


index.php是整個web應用的進入點,所有的使用者請求都會經過它。我們會寫一些代碼來把使用者請求指派到相應的控制器中,這些控制器存放在controllers檔案夾裡。之後,我們就可以用下面的方式來實現頁面跳轉:

  • http://你的網域名稱.com/index.php?page1
  • http://你的網域名稱.com/index.php?page2
  • http://你的網域名稱.com/index.php?page3

設定前端控制器index.php

首先在index.php中定義網站根目錄和網站網域名稱,以便在整個應用中訪問。

定義了網站根目錄後,在任何php檔案中,都能很方便的引用其它目錄的php檔案,因為index.php是入口檔案,這樣就能夠在整個應用中訪問在它之中定義的這些變數。

設定路由器router.php(轉寄使用者請求到相應控制器)

在controllers目錄下建立一個檔案,名字為“router.php",這個檔案用來處理所有頁面請求。想像一下你家裡的路由器,它負責把internet路由到家中的每個電腦。router.php檔案將會擷取傳入到index.php的頁面請求,然後把請求指派給不同的控制器(controllers)。

route.php中的代碼:


這句代碼會擷取傳入到應用中的請求參數。QUERY_STRING就是”?“後面的所有字串。

  • http://你的網域名稱.com/index.php?page1

上面的地址會在代碼中得到”page1&action=login“,為了把page1和後面的參數分開,我們需要在route.php中繼續加入下列代碼:

//解析$request變數,得到使用者請求的頁面(page1)和其它GET變數(&分隔的變數)如一個請求http://你的網域名稱.com/index.php?page1&article=buildawebsite,則被解析為array("page1", "article=buildawebsite")$parsed = explode('&' , $request);//使用者請求的頁面,如上面的page1,為$parsed第一個變數,shift之後,數組為array("article=buildawebsite")$page = array_shift($parsed);//剩下的為GET變數,把它們解析出來$getVars = array();foreach ($parsed as $argument){    //用"="分隔字串,左邊為變數,右邊為值    list($variable , $value) = split('=' , $argument);    $getVars[$variable] = $value;}//這是測試語句,一會兒會刪除print "The page your requested is '$page'";print '
';$vars = print_r($getVars, TRUE);print "The following GET vars were passed to the page:
".$vars."
";

現在我們需要在index.php中引入route.php

如果順利的話,你可以開啟瀏覽器輸入:


  • http://你的網域名稱.com/index.php?news&article=howtobuildaframework

我們會看到如下輸出

The page you requested is 'news'The following GET vars were passed to the page:Array([article] => howtobuildaframework)

如果沒有上述輸出,請檢查你的伺服器配置是否正確,並檢查代碼是否有錯誤。

現在來讓我們添加一個頁面到我們的網站裡,這樣就可以讓router.php來產生一個頁面,而不是直接輸出上面的資訊。


建立一個控制器(controller)

在controllers檔案夾裡建立一個檔案名稱為“news.php",定義如下的類:

';        $vars = print_r($getVars, TRUE);        print         (            "The following GET vars were passed to this controller:" .            "
".$vars."
" ); }}

注意我們把route.php中的測試代碼複製過來了,並做了一些修改,我們把它放置在main函數裡。現在讓我們來修改route.php中的代碼:

_Controller”,即News_Controller)    $class = ucfirst($page) . '_Controller';    //初始化對應的類    if (class_exists($class))    {        $controller = new $class;    }    else    {        //類的命名正確嗎?        die('class does not exist!');    }}else{    //不能在controllers找到此檔案    die('page does not exist!');}//一但初始化了控制器,就調用它的預設函數main();//把get變數傳給它$controller->main($getVars);?>

再次訪問http://你的網域名稱.com/index.php?news&article=howtobuildaframework,你將會看到從News_Controller列印出來的資訊。注意,我們現在用die()來處理錯誤,我們可以用其它更好的錯誤處理來規制它,但現在使用die()足夠了,試試訪問其它頁面如http://你的網域名稱.com/index.php?books,你會看到"page does not exist!"錯誤。建立一個Model(模型)完善News_Controller。假設我們有一些新聞片段來供讀者閱讀,那麼就需要News_Controller這個控制器去調用一個模型來抓取相關的新聞片段,無論它們是儲存在資料庫還是檔案裡。在models檔案夾裡建立一個檔案,“news.php”,代碼如下:


現在,我們需要對新聞控制器稍做一些更改,開啟controllers裡的news.php,把News_Controller類的main函數的代碼改為如下,這樣,我們就會在“News_Model”初始化時,看到列印在螢幕上的資訊:

public function main(array $getVars){    $newsModel = new News_Model;}
現在重新整理頁面,你會看到:

Fatal error: Class 'News_Model' not found in /var/www/mvc/controllers/news.php on line xx
等一下,這不是我們想要的結果!我們正試圖去載入一個不存在的類。那麼原因就是我們並沒有引入/models/news.php檔案。為瞭解決這個問題,讓們重新來看一下router.php,然後在它的頂部添加一些代碼:

//當類初始化時,自動引入相關檔案function __autoload($className){    //解析檔案名稱,得到檔案的存放路徑,如News_Model表示存放在models檔案夾裡的news.php(這裡是作者的命名規範)    list($filename , $suffix) = split('_' , $className);    //構成檔案路徑    $file = SERVER_ROOT . '/models/' . strtolower($filename) . '.php';    //擷取檔案    if (file_exists($file))    {        //引入檔案        include_once($file);            }    else    {        //檔案不存在        die("File '$filename' containing class '$className' not found.");        }}
這個函數重載了PHP內建的autoload函數。當我們試圖去初始化一個不存在的類時,這個‘魔術方法’允許我們攔截php所執行的動作。通過使用__autoload函數,我們能夠告訴php尋找包含此類的檔案的位置。假設你遵循了這篇文章中類和檔案名稱的命名規範,那麼每當你初始化一個類時,你就不必手動去引入包含此類的檔案了!

儲存route.php,再重新整理一次瀏覽器,你會看到:

I am the news model

讓我們在新聞模型類裡定義一些函數來提供文章。現在,我們只簡單的定義了一個數組,並儲存一些文章,然後提供一個函數,讓控制器從中根據標題擷取一篇文章。修改models/news.php:


 array        (            'title' => 'New Website' ,            'content' => 'Welcome to the site! We are glad to have you here.'        )        ,        //2        'mvc' => array        (            'title' => 'PHP MVC Frameworks are Awesome!' ,            'content' => 'It really is very easy. Take it from us!'        )        ,        //3        'test' => array        (            'title' => 'Testing' ,            'content' => 'This is just a measly test article.'        )    );    public function __construct()    {    }    /**     * 根據標題擷取文章     *      * @param string $articleName     *      * @return array $article     */    public function get_article($articleName)    {        //從數組中擷取文章        $article = $this->articles[$articleName];            return $article;    }}?>

現在修改controllers/news.php中的main函數:

public function main(array $getVars){    $newsModel = new News_Model;        //擷取一篇文章    $article = $newsModel->get_article('test');        print_r($article);}
現在我們並沒有考慮過濾使用者輸入的問題,因為我們現在只是為了儘快讓大家掌握PHP MVC的基本內容,所以我們現在不必太關心這些。

如果訪問如下網址:

§ http://yourdomain.com/mvc/index.php?news&article=test

你會看到如下輸出:

Array ( [title] => Testing [content] => This is just a measly test article. ) 

建立視圖(VIEW

現在我們已經有控制器和模型了,只差一個視圖。視圖是表現層,它是你的應用中,與使用者接觸最頻繁的部分。之前我提到過,視圖是提供與商務邏輯分離的使用者介面,有很多方法可以做到這個。你可以使用模板引擎Smarty或其它類似的。你也可以寫一個自己的模板引擎,但那肯定是相當艱巨的任務。最後,你可以使用原生php視圖。

對於目前來說,php視圖足夠了。這個就像以前php與html代碼混合編程一樣,但是有一點不同是,我們的商務邏輯已經和視圖分離了。看一下如下代碼:

                

Welcome to Our Website!

News

注意,嵌入的php標籤利用了PHP 快捷操作符。這樣就能夠把我們的內容直接輸出到HTML裡面了。在views檔案夾裡建立一個檔案“news.php”,把上述代碼拷貝進來。現在我們有了視圖檔案,但是我們需要一個與視圖互動的方法。在models檔案夾裡建立一個檔案“view.php”,添加如下代碼:


render = $file;        }            }    /**     * 接受從控制器賦予的變數,並儲存在data數組中     *      * @param $variable     * @param $value     */    public function assign($variable , $value)    {        $this->data[$variable] = $value;    }    public function __destruct()    {        //把類中的data數組變為該函數的局部變數,以方便在視圖模板中使用        $data = $this->data;            //渲染視圖        include($this->render);    }}

現在,最後一件要做的事就是從News_Controller裡載入視圖。修改controllers/news.php:

get_article($getVars['article']);          //建立一個視圖,並傳入該控制器的template變數          $view = new View_Model($this->template);          //把文章資料賦給視圖模板          $view->assign('title' , $article['title']);          $view->assign('content' , $article['content']);      }}?>


再載入頁面,你就能夠看到你的視圖模板中的變數,已經被正確的替換掉了。好了,你的簡單的MVC架構已經搭建好了,下面我會繼續講《開發自己PHP MVC架構(二)》

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.