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

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

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

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

路由匹配迭代过程

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


01

02

03

04

05

06

07

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()方法,获得了前端控制器的引用。


01

02

03

04

05

06

public function addRouter($name, Mage_Core_Controller_Varien_Router_Abstract $router)

{

    $router->setFront($this);

    $this->_routers[$name] = $router;

    return $this;

}

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


01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

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路由对象中一探究竟。

时间: 2024-10-26 05:43:56

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

Magento路由分发过程解析(二):Standard路由对象(转)

本文主要关注Magento的standard路由对象中的Mage_Core_Controller_Varien_Router_Standard::match()方法,该方法在前端控制器中调用,主要用来检查当前请求的URL地址,并决定匹配的模块,控制器以及方法,并且最后调用控制器分发该方法. 对于在上篇文章前端控制器循环所有的路由器来说,该方法完成了以下任务, 路由对象提供match()方法,并检测请求对象,如果匹配,则该路由对象获取该请求. 将请求标记为已分发. 设置请求对象. 假设没有找到匹配

volley源码解析(四)--CacheDispatcher从缓存中获取数据

从上一篇文章我们已经知道,现在要处理的问题就是CacheDispatcher和NetworkDispatcher怎么分别去缓存和网络获取数据的问题,这两个问题我分开来讲. 但是首先说明的是,这两个问题其实是有联系的,当CacheDispatcher获取不到缓存的时候,会将request放入网络请求队列,从而让NetworkDispatcher去处理它: 而当NetworkDispatcher获得数据以后,又会将数据缓存,下次CacheDispatcher就可以从缓存中获得数据了. 这篇文章,就让

在ASP.NET MVC控制器中获取链接中的路由数据

在ASP.NET MVC中,在链接中附加路由数据有2种方式.一种是把路由数据放在匿名对象中传递: <a href="@Url.Action("GetRouteData","Home",new { ReturnUrl = Request.Url.PathAndQuery, x = 10})">走你</a> 一种是放在RouteValueDictionary对象中传递: <a href="@Url.Action

Android事件分发完全解析之事件从何而来

尊重原创转载请注明:From AigeStudio(http://blog.csdn.net/aigestudio)Power by Aige 侵权必究! 炮兵镇楼 上一节Android事件分发完全解析之为什么是她中我们简略地分析了事件分发机制的由来,这里要说明一点,Android(或者说任何的驱动系统)都包含大量不同类型的事件,比如按键啦.轨迹球啦.鼠标啦.触摸啦.红外线啦等等等,这里为了简化问题也为了切合实际,我们只针对触摸事件进行分析,至于其他的一些杂七杂八的事件其实都很好理解就不多说了.

MVC框架-路由分发总结

原网址将会不断更新 :   作程的技术博客  <MVC框架-路由分发总结> it.zuocheng.net 路由的类型 Route Type 无路由 No Route HTTP请求直接定位到特定的脚本文件执行.比如http://domain/news/latest.php 动态路由 依据某种动态规则进行路由和分发,一般有如下形式: 强约束URL 将Class,function 等信息隐藏在url中,请求来时,依据规则解析URL就可以定位Action函数,比如http://domain/mode

前端Vue框架 04 路由:逻辑跳转、路由传参 项目组件的数据局部化处理data(){ return{} } 组件的声明周期 组件间通信 各种第三方插件(vuex,axios,element-ui,(jq+bs))

项目初始化 """ 1)根组件:App.vue <template> <div id="app"> <router-view /> </div> </template> 2)路由配置:router/index.js const routes = [ { path: '/', name: 'Home', component: Home } ]; 3)组件:views和components文件夹 i)

Yaf零基础学习总结8-Yaf中的路由和路由协议

路由器主要负责解析一个请求并且决定什么module.controller.action被请求:它同时也定义了一种方法来实现用户自定义路由,这也使得它成为最重要的一个MVC组组件.为了方便自定义路由, Yaf摒弃了0.1版本中的自定义路由器方式, 而采用了更为灵活的路由器和路由协议分离的模式.也就是一个固定不变的路由器, 配合各种可自定义的路由协议, 来实现灵活多变的路由策略. 作为一个应用中的路由组件是很重要的,理所当然的路由组件是抽象的,这样允许作为开发者的我们很容易的设计出我们自定义的路由协

spring mvc DispatcherServlet详解之三---request通过ModelAndView中获取View实例的过程

整个spring mvc的架构如下图所示: 上篇文件讲解了DispatcherServlet第二步:通过request从Controller获取ModelAndView.现在来讲解第三步:request 从ModelAndView中获取view对象. 获取view对象一般是通过viewResolver来解析view name来完成的.若ModelAndView中view 不存在或者ModelAndView本身为null则填充默认值.代码如下: ModelAndView中view 不存在或者Mod

浅析Express中的路由与应用模式

1. 引言 Express是一个基于Node.js的轻量级web开发框架,具有体积小,使用灵活等特点.查看Express的源码,如果不计供使用的中间件,主体框架只有一千余行代码,非常简练. Express模型的核心为Express中定义的路由和路由器.分析Express源码可发现Express的路由提供多种灵活的应用模式. 我们首先介绍一下Express中的路由.路由器相关概念.结构及其特点,然后针对典型场景描述使用Express路由的四种应用模式. 2.Express中的路由与路由器 Expr