看一個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的映射關係保存到數據庫表中。 搜索引擎