作者MrMarcus (请勿忘记密码)
看板PHP
标题[闲聊] MVC pattern
时间Mon Feb 27 06:03:00 2006
前阵子在一个网站上看到一篇关於在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
1F:推 ckmarkhsu:vBulletin3.5的系统好像有用这个架构实作喔:) 02/27 07:18
2F:推 ottokang:和我在书里看到得很类似~好文! 02/27 14:05
3F:推 wawawa:好文一定要推的 02/27 16:31
4F:推 ast9869:哇勒~原来我做的网站架构就是MVC啊 orz 02/27 20:07
5F:推 kakashiliu:不知道有没有人能分享更多实做的方法? 02/28 02:23
7F:推 fillano:其实xoops2也是可以用MVC实做的,extends他的XoopsObject 02/28 13:57
8F:→ fillano:还有XoopsObjectHandler把资料包装成Model不知道算不算 02/28 13:59
9F:推 oiolong:好文必推! 03/09 18:10