[閒聊] MVC pattern

看板PHP作者 (請勿忘記密碼)時間19年前 (2006/02/27 04:40), 編輯推噓8(801)
留言9則, 8人參與, 最新討論串1/1
前陣子在一個網站上看到一篇關於在PHP程式中使用MVC設計模式的文章, 覺得挺有意思的。MVC(Model-View-Controller)模式相信不少人聽過, 但是這篇文章是我看過的裡面以非常明確的例子來說明在PHP程式裡面使用 MVC模式的一篇。是一篇很短的文章,但是卻在很短的篇幅裡面提供了 不少有用的東西。 model負責包裝應用程式邏輯,將資料在各種型態之間作轉換(將資料庫中 儲存的資料轉換為另一種格式並回傳,或者將接收到的資料轉換為適於 儲存的格式並存入)。view負責將資料呈現給客戶端。controller則是 兩者的橋樑,負責流程控制。 以一個產品型錄的網站應用程式為例子,使用MVC模式的架構簡單來看是: ProductView | | Request data | Client --------------------> ProductController <=================== | Result (HTML/XML/CSV...) | | ProductModel(getProducts(), getProductById()...) | |-----|----|----| | | | | TEXT XML DB SMTP... 現在假設來自客戶端的要求是呈現id為101的產品資料: 1. controller是直接面對客戶端的唯一接觸點,來自客戶端的資料都是由controller 接收,最後要呈現給客戶端的資料也是由controller回傳給客戶端。此時controller 從客戶端接收到兩項資訊:1.我要看的畫面是商品詳細資料 2.商品的識別碼是101。 2. controller首先驗證接收到的資料是否有效,它必須確認1.我們確實有提供商品 詳細資料畫面這項功能,以及2.商品的識別碼是有效的。但是controller本身並不負責 實作驗證資料的相關邏輯,資料如何被驗證應該實作在model裡面,controller只是 呼叫model提供的資料驗證方式,傳入資料並且依照model回傳的結果決定下一步驟。 因此此時controller所執行的步驟類似: if(ProductModel::is_valid_id($_GET['prod_id'])) { // 商品識別碼有效 } else { // 商品識別碼無效 } 3. 資料驗證後有效後,controller呼叫由model所提供的功能,傳入需要的參數 並且取回由model轉換整理過後的資料: $prod_data = ProductModel::getProductById($_GET['prod_id']); 商品資料以何種型式儲存在何種媒介之中,只有model知道。也許商品資料被存放在 資料庫中,分散在三個資料表裡面。model會負責取出必須的資料,整理成有意義的 格式並且回傳。這裡所謂有意義的格式也許是一個物件,或者一個hashtable,重點 在於這個格式和最後資料會如何被呈現完全無關。model並不知道這項資料是要被 顯示在一般瀏覽器上(HTML)或者顯示在手機上面(WML),或者其他型式。 4. 從model取回的資料,必須轉換成客戶端可了解的型式,這部分是view的責任。 因此controller將取回的商品資料,連同其他必要指示,傳送給view。 $instructions = array( 'page' => 'product_detail', 'client_type' => 'standard_browser' ); $output = ProductView::get_output($instructions, $prod_data); view根據接收到的指示與資料,將$prod_data(也許是一個hashtable)轉換成 顯示商品詳細資料的HTML原始碼(因為client_type='standard_browser',也許 如果client_type=smart_phone,view就會傳回WML格式的資料,whatever)。 5. 現在controller得到了可以回傳給客戶端的HTML。這時候它可以直接回傳給 客戶端: echo $output; 或者也許controller從瀏覽器類型得知這是個簡體版的瀏覽器,因此把$output 轉換成簡體字之後再傳送給客戶端: $output = CharConverter::trad_to_simp($output); echo $output; 以上的架構中,model, view, controller三種角色區分得很清楚。依照個人的經驗, 在實際寫的時候,從程式碼之中可以觀察到以下的特性: 1. controller裡面不會有任何HTML,因為它不負責資料如何呈現。 2. controller裡面不會有任何SQL或者fopen()因為它不負責資料如何儲存與取得。 3. model裡面不會有任何HTML(同上)。 4. model是唯一會存取資料庫,資料檔,SMTP server或者其他資料媒介的地方。 5. model裡面不會出現echo(), print(), header(), exit, 這些只出現在controller。 6. view裡面不會出現SQL/fopen(), echo(), print(), header(), exit... 7. view是唯一會出現HTML/XML/CSV...的地方。不過若搭配樣板引擎,view裡面也 不會有這些,樣板檔案裡面才有。 8. model以及view裡面都不會直接存取$_GET, $_POST, $_COOKIE這些資料。 9. model裡面才會出現資料結構與演算法(不論複雜程度如何),controller/view 裡面只會有很簡單的if/else/switch,controller裡面甚至不會出現迴圈。 10. model與view對彼此一無所知,controller是兩者的中介。 以上是個人對於在PHP程式裡面使用MVC模式的一些心得,歡迎一起討論:) -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.115.146.31

02/27 07:18, , 1F
vBulletin3.5的系統好像有用這個架構實作喔:)
02/27 07:18, 1F

02/27 14:05, , 2F
和我在書裡看到得很類似~好文!
02/27 14:05, 2F

02/27 16:31, , 3F
好文一定要推的
02/27 16:31, 3F

02/27 20:07, , 4F
哇勒~原來我做的網站架構就是MVC啊 orz
02/27 20:07, 4F

02/28 02:23, , 5F
不知道有沒有人能分享更多實做的方法?
02/28 02:23, 5F

02/28 05:51, , 6F
02/28 05:51, 6F

02/28 13:57, , 7F
其實xoops2也是可以用MVC實做的,extends他的XoopsObject
02/28 13:57, 7F

02/28 13:59, , 8F
還有XoopsObjectHandler把資料包裝成Model不知道算不算
02/28 13:59, 8F

03/09 18:10, , 9F
好文必推!
03/09 18:10, 9F
文章代碼(AID): #140X9I8h (PHP)
文章代碼(AID): #140X9I8h (PHP)