看一个url例子
http://localhost/magento/index.php/customer/account/login
这里假定http://localhost/magento/ 是magento安装目录。那么Magento将自动转而执行customer模块下名字AccountController的loginAction方法。这个是ZendFramework的默认重写规则。
另一个产品详细页的例子
http://localhost/magento/index.php/catalog/product/view/id/1/category/3
Magento将寻址catalog模块的ProductController的viewAction方法,传入参数id和category.
为了搜索引擎更加友好化,咱们可能但愿用用下面的url一样访问到该产品
http://localhost/magento/index.php/basketball/tayshaun-prince-signed-auto-baketball-with-coa-gold.html
Magento重写了ZendFramework的机制完成这个功能,它的实现思路是:当发送请求的时候,Magento首先判断 basketball/tayshaun-prince-signed-auto-baketball-with-coa-gold.html是否在数据库core_url_rewrite表中是否有该route path和实际target path映射记录,没有的话,就使用Zend Framework的重写规则寻址相应的php执行代码。
为了窥视它的Rewrite机制, 还着实费了很多力气,可是也只是懂些皮毛。下面说说我分析这个机制的过程:
仍然以访问 php
为例
1. 从magento安装目录下的index.php开始,末尾的Mage::run();很显然是程序的入口。
2. 打开app/Magento.php查看run()函数尝试在不一样的位置输出self::_$app属性(是一个类),看看有没有url关键字basketball,结果发现多处子对象有字符串属性包含它:
html
那么为了完成映射,程序必须有一处读取其中一个属性(原始url串),而后进行解析和转换。这是着实有点迷惑了,四个属性,到底哪个才是关键的呢?
3.打开Mage_Core_Controller_Request_Http类文件,先从_originalPathInfo入手(由于名字带了一个original),找到getOriginalPathInfo(), 该方法调用了setPathInfo(), 这么说这个方法应该是设置_pathInfo的函数了,结果这个发现该方法先调用getRequestUrl方法初始化属性
_requestUri,这个是url源头,而后运算出以下属性:
_originalPathInfo
_requestString
_pathInfo
4. 接着全目录搜索调用getOriginalPathInfo的类方法,找到类Mage_Core_Controller_Varien_Router_Standard。打开调用方法为match,浏览了下整个函数内容,发现了以下代码 程序员
由此能够猜想出,对于该例子,这里应该有以下的映射: 数据库
因此下面的就是要找出$moudle变量是如何计算出来的
5. 找到上面初始化$module的位置
$module = $request->getModuleName();
必定是$request的属性被某处初始化,才使得 $request->getModuleName()返回module名字。
因而代码定位到前面的
$p = explode('/', trim($request->getPathInfo(), '/'));
6. $request是Mage_Core_Controller_Request_Http类的实例,打开它的getPathInfo方法。
......哈哈
线索中断,其实这种分析方法是不推荐的,彻底没有程序员逻辑:)
线索II.
1. 从Mage::run()方法开始,程序员能够敏感地意识到下面代码的关键性 app
2.打开Mage_Core_Controller_Varien_Front的 dispatch方法 函数
3. Mage::getModel('core/url_rewrite')能够定位到Mage_Core_Model_Url_Rewrite类文件 工具
若是 $this->loadByRequestPath($requestCases);从数据库中core_url_rewrite表查找是否有对应的target_path,若是找不到return false(用默认的rewrite机制),这里应该是能够找到targe path的,即
catalog/product/view/id/1/category/3
4. 继续回到dispatch()方法,代码 if ($router->match($this->getRequest()))中
$router 是Mage_Core_Controller_Varien_Router_Standard的实例,方法match以下: this
上面代码显而易见,到此代码分析结束。
结论:这次分析是推论+推测(瞎蒙,瞎蒙就是全文搜索匹配字符串肯定调用和被调用关系),没有使用任何单步调式工具。
那么分析Rewrite机制对于扩展Magento的意义何在呢? 好比,若是你想为产品增长品牌分类,那么你可能须要定义以下的符合SEO的URL
http://localhost/magento/index.php/ibm/
使之映射到
http://localhost/magento/index.php/catalog/brand/id/2
此时,你就要定义重写机制使两个URL的映射关系保存到数据库表中。 搜索引擎