前陣子在一個網站上看到一篇關於在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模式的一些心得,歡迎一起討論:)
留言列表