Magento路由分发过程解析(一):在前端控制器中获取路由对象

Magento的路由系统,需要考虑到两个抽象层。

1,首先你需要了解,可能会有无数多个路由对象负责处理路由逻辑,最后只有一个路由对象能够获取并处理该请求。默认情况下,Magento拥有四个路由对象。

2,在这四种路由对象内,又有一系列不同的规则用于匹配url地址到相应的控制器方法。这些规则非常相似,只有一些细微的差别。

路由匹配迭代过程

Magneto的路由开始于前端控制器对象的Mage_Core_Controller_Varien_Front::dispatch()方法,在如下循环中,选择合适的路由对象,

while (!$request->isDispatched() && $i++<100) {
    foreach ($this->_routers as $router) {
        if ($router->match($this->getRequest())) {
            break;
        }
    }
}

Mage_Core_Controller_Varien_Front::$_routers是前端控制器类的一个属性,用于存放系统中可用的路由规则。该属性被定义为一个数组,默认为空,数组键为路由对象表示,如admin,standard,cms,default,对应的数组值分别为实例化的路由对象。那么它是如何被系统赋值的呢?在系统APP模型中实例化前端控制器类的时候,调用了该类的init()方法,该方法按照一定的方式,实例化系统中可用的路由对象,并通过addRouter()方法,将获取到的路由对象赋值给$_routers数组,另外,在addRouter()中,每个路由对象都通过setFront()方法,获得了前端控制器的引用。

public function addRouter($name, Mage_Core_Controller_Varien_Router_Abstract $router)
{
    $router->setFront($this);
    $this->_routers[$name] = $router;
    return $this;
}

回过头来在看init()方法,下面是该方法的完整代码,

public function init()
{
    Mage::dispatchEvent('controller_front_init_before', array('front'=>$this));
 
    $routersInfo = Mage::app()->getStore()->getConfig(self::XML_STORE_ROUTERS_PATH);
    /*  $routersInfo需要的config.xml文件节点如下
    <web>
        <!-- ... -->
        <routers>
            <admin>
                <area>admin</area>
                <class>Mage_Core_Controller_Varien_Router_Admin</class>
            </admin>
            <standard>
                <area>frontend</area>
                <class>Mage_Core_Controller_Varien_Router_Standard</class>
            </standard>
        </routers>
        <!-- ... -->
    </web>
    */
 
    Varien_Profiler::start('mage::app::init_front_controller::collect_routers');
    foreach ($routersInfo as $routerCode => $routerInfo) {
        if (isset($routerInfo['disabled']) && $routerInfo['disabled']) {
            continue;
        }
        if (isset($routerInfo['class'])) {
            $router = new $routerInfo['class'];
            if (isset($routerInfo['area'])) {
                $router->collectRouters($routerInfo['area'], $routerCode);
            }
            $this->addRouter($routerCode, $router);
        }
    }
    Varien_Profiler::stop('mage::app::init_front_controller::collect_routers');
    //这里实际上分发事件,为了添加CMS路由对象
    Mage::dispatchEvent('controller_front_init_routers', array('front'=>$this));
 
    // 最后添加默认路由
    $default = new Mage_Core_Controller_Varien_Router_Default();
    $this->addRouter('default', $default);
 
    return $this;
}

如上所述,该方法只用于收集可用路由,并使用addRouter()方法添加路由对象到属性Mage_Core_Controller_Varien_Front::$_routers中。稍微深入点的话,可以看到,在foreach循环中,每次实例化路由时,都会调用路由对象的collectRouters()方法。该方法可以在standard路由对象中一探究竟。

转载请注明:锐想Magento » Magento路由分发过程解析(一):在前端控制器中获取路由对象


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值