你的位置:面向PHP >> 资讯 >> 开发框架 >> 更多框架 >> 详细内容 在线投稿

PHP框架中MVC模型中理想的Controller

热度159票  浏览98次 【共0条评论】【我要评论 时间:2009年6月04日 21:47
Controller这种东西应该是属于MVC系列的。所以,我把它放到更多框架分类,本文是老王对于目前一些框架的控制器的看法,提出了改进的想法。对于想开发框架的朋友来说,可以作个参考。
t?&fW:|8Z`XI0
JV4S F }c_"E0现有的PHP框架,如CakePHP,其Controller的运作模式基本是类Rails的方式:面向PHPP)m~;F2E
面向PHP:@4| })d,r7p:C
class ArticlesController extends AppController {面向PHPJv.\!p9h&`
    function index() {}面向PHP `&n6D3[8pD
    function view() {}
7xP)e){fi C0     function add() {}
sERZ r[+^?0     function edit() {}
8s}cB;P4@d&[f$z0     function delete(
) {
p!h4|,}W @-Q~0         if ($this->Article->del($this->params['id'])) {
'hgh!Z1k,g2x;m0             $this->redirect(array('action'=>'index'));
}w+\"]z0         }
(X y Jakq6s@ g0     }面向PHP"_c!]CNPr pcb
}
面向PHP"U|7d7F+nd:H c_#b
面向PHP7S-XT%m*S},Z
这样的Controller很难透明扩展,主要存在以下问题:面向PHP-H ^Ia1bv+s ? c
面向PHP5Njs"H.Q Y
一:当一个请求到达时,比如说是delete,框架会实例化ArticlesController,然后调用delete方法,控制器里的其它代码如 index, view, add, edit, delete,都是和delete无关的,对PHP这样的脚本语言来说,每个请求都需要重新初始化环境,从严格意义上讲,任何不必要的多余代码对性能都是 有害的。面向PHP-t EY xK$zIm

S;?V)R D5Z.w0 二:当处理redirect的时候,由于Action一般没有形参,也没有返回值,只能使用的是直接跳转的方式,相当于在方法里硬编码了exit(),这 无疑是坏味道,如果我们想用Filter机制扩展delete的话,由于exit()的存在,后面的代码根本没有机会执行,扩展也就不可能了。面向PHPV t bD*~4M5D8I B;[
面向PHP3d];i8|j @BQ:T/C
如果我设计PHP框架,我会这样设计Controller:
(n{!vfuh+D0
ovf-o G0mQ0 class DeleteController extends Controller implements Executable面向PHP nD6d:D1vD1YW2S}
{面向PHP-d5D,~G`m~ V,pz{ Z
    protected $filters = array('Transaction');
R7V~6Nx-_g!K0 面向PHP(K4MmR ^zKNY{
    public function execute($request, $response)面向PHP3QB6~ \2QG%ce.o
    {面向PHP7f1rH9~ a&Wd}2P
        // $request->getParams('id');面向PHP!ES;g ?D*K;T;u0i&N;B
        $response->setStatus('307 Temporary Redirect');
7p,J"B%Q;k2qUF0     }
V|V-mXn V0 }
面向PHP? dj!\ p6eMGK A

-J#[;usX)`0 一:一个Action就是一个Controller,多个Action文件可以放到一个文件夹里以模块方式存在。
+Z$@.[d;RV`)x9`0 二:对于redirect,不存在硬编码exit,而是引入response对象,在前端控制器里根据状态码来控制跳转。面向PHP+Pz z&f\

mEI@$A(_I9p-X0 乍一看上去,这样的Controller设计方式类似于Java,但用意有些许不同。在Java的一些框架中,如Struts,虽然也把 request,response作为Controller形参,但之所以这样做是因为request,response都是有状态的,通过剥离它 们,Controller对象本身就变成了无状态的,从而可以在各个请求间得以复用。但是PHP每次请求都要重新建立运行环境,所以本质上是不可能在各个 请求间复用Controller对象的,对PHP而言,真正的意义在于,这样的设计给了Controller更灵活,更透明的扩展方式,比如说透明事务处 理:面向PHPs0\ E'O8o\(u
面向PHP ZV"c0|vf|
class TransactionFilter extends Decorator implements Executable面向PHPTi5z'W.ON8mSi!f*c
{
A o\7T;|e5W/aX0     public function execute($request, $response)
h6@1YaQ|"L0     {面向PHP/O(lK(s ]yH^
        try {面向PHP)@%h9B#X J P6z;q5q
            // Transaction begin
yuq"GV3rI0             $this->Controller->execute($request, $response);面向PHPbf[,L P.z V
            // Transaction commit
8S)jnB:g2[%d:IA0         } catch (Exception $e) {面向PHP\E(A*~v
            // Transaction rollback
9P0zE)e T |0         }
-xD4} Y:t(w$B p0     }
*k1uKD7ljS"~*v0 }

NRi6n*f3k(@0 面向PHPvu)VZ3I5^9C$Uj
在前端控制器里,利用装饰器等模式,可以很容易的把Controller和Filter整合到一起(参考链接),从而透明的给DeleteController加上事务处理的功能,类似的,还可以透明的加上更多的Filter,从而给了Controller无限扩展的能力。面向PHP%DiE3g3Ce$i
TAG: PHP php 框架 MVC Controller 模型
顶:12 踩:13
对本文中的事件或人物打分:
当前平均分:-0.16 (43次打分)
对本篇资讯内容的质量打分:
当前平均分:0.19 (47次打分)
【已经有44人表态】
8票
感动
2票
路过
6票
高兴
6票
难过
4票
搞笑
4票
愤怒
6票
无聊
8票
同情
上一篇 下一篇
发表评论

网友评论仅供网友表达个人看法,并不表明本网同意其观点或证实其描述。

查看全部回复【已有0位网友发表了看法】