The Magento routing system requires two layers of abstraction to be considered.
1, first you need to understand that there may be countless multiple routing objects that are responsible for handling routing logic, and finally only one routing object can get and process the request. By default, Magento has four route objects.
2, in these four kinds of routing objects, there are a series of different rules to match the URL address to the corresponding controller method. These rules are very similar, with only a few subtle differences.
Route matching Iteration Process
Magneto routing starts at the front controller object's Mage_core_controller_varien_front::Dispatch () method, in the following loop, select the appropriate routing object,
01020304050607 |
while (!
$request
->isDispatched() &&
$i
++<100) {
foreach (
$this
->_routers
as $router
) {
if (
$router
->match(
$this
->getRequest())) {
break
;
}
}
}
|
mage_core_controller_varien_front::$_routers is a property of the front controller class that holds the routing rules available in the system. The property is defined as an array, which is empty by default, and the array key is a route object representation, such as Admin,standard,cms,default, where the corresponding array value is an instantiated routing object. So how is it assigned to the system? When instantiating the front-end controller class in the System app model, the Init () method of the class is called, which instantiates the available routing objects in the system in a certain way, and assigns the obtained route object to the $_routers array through the Addrouter () method, in addition, In Addrouter (), each routing object obtains a reference to the front controller through the Setfront () method.
010203040506 |
public function addRouter(
$name
, Mage_Core_Controller_Varien_Router_Abstract
$router
)
{
$router
->setFront(
$this
);
$this
->_routers[
$name
] =
$router
;
return $this
;
}
|
Looking back at the init () method, here is the complete code for the method,
010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445 |
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
;
}
|
As mentioned above, this method is only used to collect available routes and use the Addrouter () method to add the route object to the attribute mage_core_controller_varien_front::$_routers . A little bit deeper, you can see that in a foreach loop, each time you instantiate a route, the Collectrouters () method of the routing object is called. This method can be used to explore the standard routing object.
Magento Routing Distribution Process resolution (i): Get the Routing object in the front controller (GO)