代码改变世界

关于ZendFramework的Plugin

2008-10-26 15:20  Jaypei  阅读(541)  评论(0编辑  收藏  举报

因为要做ACL,不知道该把代码放到何处,于是读了一点ZendFramework的代码,发现ZF的Plugin实现的的确很漂亮。

ZendFramework从index.php中的dispatch()到controller、action、template,中间主要是做了对URL的解析分发处理和产生Request的工作,而这个过程是通过开发者使用Plugin进行干预的。

从代码中看到,包括Zend_Controller_Plugin_Broker在内的所有Plugin都继承自Zend_Controller_Plugin_Abstract。在Zend_Controller_Front的构造函数中初始化了一个Zend_Controller_Plugin_Broker的实例$_plugin,由于Zend_Controller_Front用单例模式保证唯一,从而也保证了$_plugin唯一。

class Zend_Controller_Plugin_Abstract {
    
protected $_request;
    
protected $_response;

    
// 对$_request和$_response的包装
    function getResponse(…);
    
function setResponse(…);
    
function getRequest(…);
    
function setRequest(…);
    
    
// 为事件预留的方法接口
    function routeStartup($request);
    
function routeShutdown($request);
    
function dispatchLoopStartup($request);
    
function preDispatch($request);
    
function editDispatch($request);
    
function dispatchLoopShutdown($request);

}

class Zend_Controller_Plugin_Broker extends Zend_Controller_Plugin_Abstract {
    
protected $_plugins = array();

    
// 对$_plugins的包装
    function registerPlugin(…);
    
function unregisterPlugin(…);
    
function hasPlugin(…);
    
function getPlugin(…);
    
function getPlugins(…);
    
    
// 对$_request和$_response的包装(对$_plugins中的plugins遍历set)
    function setRequest(…);
    …

    
// 实现事件的各个方法接口
    // 根据$_plugins的顺序依次调用并做异常判断

    function routeStartup($request) { … }
    …
}

看到这里大体就明白了ZF对Plugin的处理过程,在消息处理过程中的相应地方就会通过Zend_Controller_Plugin_Broker的唯一实例调用所有在dispatch()前注册过的Plugins的相应事件方法。

若想自定义Plugin只需自定义一个类,继承Zend_Controller_Plugin_Abstruct,实现提供的事件方法就可以Hook任何处理过程中的位置做特殊处理。然后使用Zend_Controller_Front::getInstance()->registerPlugin()把自定义的Plugin注册进去就生效了。

我的ACL就可以往这里放了:)