PHP框架如何實現MVC模式以及單一入口

2022-02-09 03:23:55 字數 3647 閱讀 5977

這裡不詳細講解何為mvc模式,只是簡單介紹,關於mvc的具體資訊可以去網路上找尋,mvc模式在我理解來它將乙個專案分解成三部分,分別是model(模型),view(檢視),controller(控制器),這三個單詞的縮寫組合即為mvc.mvc是一種普遍的軟體敏捷開發模式,在許多領域特別是桌面程式設計領域早已經得到了廣泛的應用,然而在像php一樣的指令碼語言中比較難以實現,特別是幾年前在指令碼語言中很難看到mvc的實現,但是今年隨著眾多框架的湧現,mvc在各個框架中得到了初步實現,其他框架中的實現方式暫且不提,這裡只是介紹codeigniter是如何實現mvc的.

關於單一入口

單一入口指在乙個**(應用程式)中,所有的請求都是指向乙個指令碼檔案的,例如ci中的http:\\localhost\index.php,所有對應用程式的訪問都是必須通過這個入口,正是單一入口才使得mvc模式得以實現,因為當你訪問index.php的時候,應用程式會做大量的初始化工作,呼叫大量的基礎類庫,並根據index.php後面的引數載入控制器,然後載入試圖,模型等內容資訊.

ci的官方文件非常詳盡易懂,這裡描述的是文件上所不存在的基本原理部分.

開始

1 class controller extends controller 2 3 ncontroller()45parent::controller(); 6 7 8 n func($m1,$m2)910$this->load->model("msomemodel","",true);11$data["data1"]=$this->msomemodel->getvalue();12$this->load->view("welcome",$data);131415

這並不是乙個控制器的基本組成部分,而是包含了model和view的乙個控制器例子,

首先注意控制器的類名應該是首字母大寫的,然後在類的建構函式裡應該呼叫父類的建構函式,之後則是func()方法,也就是url後面所帶引數的第二個部分,這個方法帶有兩個引數,這兩個引數的值就是url的第三部分和第四部分的值,也就是單一入口的訪問方式實際是:http:\\localhost\index.php\控制器名\方法名\方法的引數1\方法的引數2\......

在控制器類中每個方法代表乙個頁面,也就是可以將很多類似的操作放到乙個控制器中,實現對操作的統一

在上述的例子中的func()方法中的其他部分分別載入了model和view,載入model的時候載入的是在models資料夾中的msomemodel.php檔案中的msomemodel類,這個類負責應用程式的模型部分,也就是負責資料的交換,例如資料庫的儲存.

然後我們通過$data=$this->msomemodel->getvalue()執行了model中的乙個方法,並從這個方法返回了資料,然後賦值給$data["data1"],$data是乙個關聯陣列,我們通過這個陣列向view視**件傳值,而不是使用常見的模板模式,這種方法更好地分離了mvc各個部分的處理,同時在效能方面有其獨特的一面.

之後我們通過將$data陣列傳給views資料夾中的welcome.php檔案,這個檔案是常規的php和html混寫的指令碼,在這個指令碼中可以利用傳過來的$data陣列輸出資訊,但是注意在view檔案中輸出資訊的時候不必使用$data["data1"],而只需要echo$data1;即可.

基本的工作方式就是這樣的,下面從**級別來分析實現

**分析

在ci中將controller類作為超類來處理,也就是所有載入mvc實現模式的程序都從controller類開始,所以我們忽略ci在載入到這個類的時刻前面的執行過程,而直接從controller類所在的檔案開始分析.

controller類所在的檔案位於system/libraries/controller.php檔案中.

在這個類中首先載入了所有必須的基礎類,包括:"config","input", "benchmark","uri","output", "language","router"類.之後載入roader類並執行了它的_ci_autoloader()方法,這個類是mvc模式的核心,控制器中所有其他內容的載入都是通過它實現的,下面對其**進行分析:

首先來看_ci_autoloader()方法,這個函式實現了自動載入某些類庫或者類,如果在你的應用程式中總是要用到某些類,但是你又不確保在ci中是否已經自動載入了這些類的話,你可以在config/autoload.php檔案中設定要自動載入的library或者helper或者plugin的陣列.具體請參考手冊.

首先看看ci是如何載入libraries的,這個方法允許你在你的控制器的任何地方(通常是建構函式裡)使用$this->load->library("name");來載入某個類,這個類可以是使用者自定義的類也可以是系統的類庫,使用者自定義的類需要遵循ci的約定,具體資訊見手冊中的"建立你自己的類庫"部分.library()方法以乙個字串或者乙個類庫名稱的陣列作為第乙個引數,之後的處理將遍歷然後載入所有的類,你可以通過第二個引數向要載入的類的建構函式傳遞引數,第三個引數允許你定義返回的物件的名稱,後面的兩個引數通常不使用,這個方法在簡單判斷了引數是否為空之後呼叫了方法_ci_load_class($class,$ms= null, $t_name=null),這是乙個非常複雜的函式,這個類載入第乙個引數所指定的類,在這個類中進行了複雜的路徑判斷之後找到了所需要的類檔案之後,呼叫了方法_ci_init_class($class,"",$ms,$t_name);這個類用來例項化乙個類,如果在載入這個類的語句中包含了上述的第三個引數,則返回乙個例項,以這個引數作為例項名,如果沒有設定第三個引數,則返回乙個以類名命名的例項名,這也是為什麼前面的例子中在載入了model之後,直接將model類名作為乙個物件使用的原因.

之後我們來看ci是如何載入模型的,這個方法允許你在控制器中使用$this->load->model($modelname,$name,$db_conn)載入模型,這三個引數分別是載入的模型的名稱,載入後例項化的物件名稱,是否自動連線資料庫.後面兩個引數可以省略,你可以講多個模型一次載入,只需要將第乙個引數設定成陣列即可,這個方法首先將傳過來的第乙個引數以"\"分解成陣列,這種機制允許你在模型中建立多層資料夾,更加合理地安排**的分組,之後程式取出陣列的最後乙個元素作為要載入的類的名稱,並根據路徑尋找此類,之後包含此檔案,並例項化此類,如果設定了第二個引數,則例項化到$name的物件中,否則預設以類名作為物件名進行例項化.

再來看ci是如何載入檢視的,view($view, $vars = array(), $return=false)方法的第乙個引數是要載入的檢視名稱,第二個引數是要傳給檢視的變數值,第三個引數指定是否返回輸出緩衝區的資料.這個方法將所有陣列作為乙個陣列引數呼叫了_ci_load($_ci_data)方法,這個方法將傳過來的變數陣列通過extract()函式解析成符號表(也就是將鍵名當作變數名,值作為變數的值),並將這些變數快取起來,以便可以再不同的檢視中能夠互相交流變數,也就是這個方法允許呼叫多次,為了在每次呼叫時都能自動載入已經傳給前面檢視的變數,將所有傳給檢視的變數都快取在類的乙個屬性中,這樣每次呼叫方法的時候都會獲取所有的變數.之後載入這個視**件,然後將其作為輸出緩衝的一部分賦給全域性變數$out,這個變數用來控制緩衝輸出,這樣做可以提高效率以及可以使除錯的時間更準確.

其他的載入方法和上述的方法原理基本相同,只是根據情況有少許改變,ci在實現mvc模式的方法中將所有的檔案都包含在控制器中,我們在包含了這些檔案後,可以再控制器中自由使用這些物件和資料,然後最後通過緩衝輸出類來輸出所有的資料,雖然loader這個類的結構看起來很複雜,但是其實它的實現時很簡單的,其內部的**原理基本相同,而且清晰明了,仔細看的話不難理解.

PHP之簡單實現MVC框架

1.概述 mvc全名是model view controller,是模型 model 檢視 view 控制器 controller 的縮寫,一種軟體設計典範,用一種業務邏輯 資料 介面顯示分離的方法組織 將業務邏輯聚集到乙個部件裡面,在改進和個性化定製介面及使用者互動的同時,不需要重新編寫業務邏輯。...

PHP之簡單實現MVC框架

1.概述 mvc全名是model view controller,是模型 model 檢視 view 控制器 controller 的縮寫,一種軟體設計典範,用一種業務邏輯 資料 介面顯示分離的方法組織 將業務邏輯聚集到乙個部件裡面,在改進和個性化定製介面及使用者互動的同時,不需要重新編寫業務邏輯。...

MVC模式框架

1.什麼是mvc模式框架 1.mvc 就是 model 模型 view 檢視 controller 控制器 這三個單詞的簡稱。也被稱為設定框架 2.一種軟體設計典範,用一種業務邏輯 資料 介面顯示分離的方法組織 將業務邏輯聚集到乙個部件裡面,在改進和個性化定製介面及使用者互動的同時,不需要重新編寫業...