11. Magento路由分发过程解析(一):在前端控制器中获取路由对象
2015-06-24 15:13
656 查看
Magento的路由系统,需要考虑到两个抽象层。
1,首先你需要了解,可能会有无数多个路由对象负责处理路由逻辑,最后只有一个路由对象能够获取并处理该请求。默认情况下,Magento拥有四个路由对象。
2,在这四种路由对象内,又有一系列不同的规则用于匹配url地址到相应的控制器方法。这些规则非常相似,只有一些细微的差别。
路由匹配迭代过程
Magneto的路由开始于前端控制器对象的Mage_Core_Controller_Varien_Front::dispatch()方法,在如下循环中,选择合适的路由对象,
回过头来在看init()方法,下面是该方法的完整代码,
如上所述,该方法只用于收集可用路由,并使用addRouter()方法添加路由对象到属性Mage_Core_Controller_Varien_Front::$_routers中。稍微深入点的话,可以看到,在foreach循环中,每次实例化路由时,都会调用路由对象的collectRouters()方法。该方法可以在standard路由对象中一探究竟。
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路由对象中一探究竟。
相关文章推荐
- jQuery中$.extend()用法实例
- 深入理解JavaScript编程中的同步与异步机制
- datatable转json
- javascript字符串相关的面试题总结
- 用 FastJson 解析 Json.
- 前端学习视频教程angular
- 用 jsoup 解析 Html.
- 在4.0.5版本的内核中配置 NUMA balancing 找不到/sys/kernel/debug/sched_features 文件?
- [Javascript] IIFE
- FileResult,JavaScriptResult,JsonResult
- 应用before/after伪类时如何CSS命名以及针对ie6/ie7浏览器兼容
- LeetCode Swap Nodes in Pairs
- js 对象数组根据对象中的属性排序
- 使用HTML辅助方法载入分部视图
- wp7 webbrowser+html5 打造本地应用程序
- view如何从action中取得数据和 Html辅助方法
- 剑指offer 36 - 数组中的逆序对
- 遍历JSON、获取JSON长度的方法
- 详解JavaScript中的客户端消息框架设计原理
- js typeof instanceof