如下是分別詳細解讀分析Magento 程序的各層次源碼:php
MAGENTO_ROOT:css
入口文件 /index.phphtml
|sql
1.判斷php版本是否大於5.2
2.引入Magento主要的中心類/app/Mage.php
3.判斷是否已經下載安裝,是否站點維護,是否開發模式
4.執行Mage::run,網站前臺的主要入口點。瀏覽器
|緩存
/app/Mage.php run()session
1.開始Varien_Profiler::start(),這個類的做用是方便開發過程當中的代碼性能分析,各個profiler各消耗多少內存和 時間。默認是禁用的,開啓須要登陸後臺在」System > Configuration > Advanced > Developer > Debug > Profiler 設置爲 Yes」,頁面底部會提示總的內存使用狀況,同時index.php文件中取消註釋#:Varien_Profiler::enable();則顯示每一個 單元的消耗。
2.建立一個app實例,new Mage_Core_Model_App();架構
|app
Mage/Core/Model/App.php run()frontend
1.判斷是否有緩存,有則直接返回;
2.沒有Cache則初始化模塊、商店並:
3.初始化請求:$this->_initRequest();經過Mage/Core/Controller/Request/Http.php的setPathInfo()方法。
4.從新交給前臺控制器(Mage_Core_Controller_Varien_Front)先初始化$this->getFrontController():$this->_frontController->init();
|
Mage/Core/Controller/Varien/Front.php init()
1.dispatchEvent(‘controller_front_init_before’)
2.初始化過程當中經過addRouter()添加路由和路由類型。
3.dispatchEvent(‘controller_front_init_routers’)
4.addRouter()添加默認路由。
5.初始化後再進行dispatch:$this->getFrontController()->dispatch().
|
Mage/Core/Controller/Varien/Front.php dispatch()
1.判斷是否啓用了url_rewrite,有則先進行重寫:Mage/Core/Model/Url/Rewrite.php rewrite() line 195.
2.將收集到的路由與請求進行匹配match:$router->match($this->getRequest()),由路由類型決定採用哪一種router,好比標準router:
|
Mage/Core/Controller/Varien/Router/Standard.php match()
1.從$request獲取module、controller、action名稱。
2.經過Mage::getControllerInstance()實例化獲取到的controller類。
3.對實例化的controller進行分發:$controllerInstance->dispatch($action);
|
Mage/Core/Controller/Varien/Action.php dispatch()
1. preDispatch();(Mage::dispatchEvent)
2. 正式執行action的業務邏輯:$this->$actionMethodName();
3. postDispatch();(Mage::dispatchEvent)
至此,Magento Dispatch所有完成,進入action執行url請求的業務邏輯,開始正式引入MVC架構
Magento的 app/code/core/Mage/ 核心代碼以模塊方式組織文件,先看下每一個模塊下的文件結構:
其中 controllers 顧名思義控制器,至關於控制中樞執行業務邏輯。下面以user請求/catalog/category/view/id/8/這個url爲例進行說明,首 先magento的router會依次匹配 catalog Model -> category controller -> view action -> 參數id爲8,即 Catalog/controllers/CategoryController.php 類中的viewAction() 方法,能夠看出 Magento 這裏的命名格式爲 ***Controller.php ***Action()。下面看下viewAction() 執行的邏輯:
1. _initCatagory()初始化category並加載該產品分類的數據。
- (Mage::dispatchEvent before)
- 從請求中獲取分類id:$categoryId = (int) $this->getRequest()->getParam(‘id’, false); //8
- Model層加載分類數據:Mage::getModel(‘catalog/category’) ->load($categoryId); 單態模式的Model:Mage::getSingleton(‘catalog/session’)
- Helper類幫助函數:Mage::helper(‘catalog/category’) ->canShow($category)
- (Mage::dispatchEvent after)
2. 控制器初始化分類和加載分類成功後:
Design
- 獲取該分類的design設置:$settings = Mage::getSingleton(‘catalog/design’)->getDesignSettings($category);
- 應用自定義的design package和theme (如有自定義):$design->applyCustomDesign($settings->getCustomDesign()); Mage_Catalog_Model_Design
Layout
- 添加default handle:$update = $this->getLayout()->getUpdate()->addHandle(‘default’); Mage_Core_Model_Layout_Update
- 添加當前Action handle:$this->addActionLayoutHandles(); /Mage/Core/Controller/Varien/Action.php
- 添加其餘handle:……
- 更新Layout:$this->loadLayoutUpdates(); /Mage/Core/Controller/Varien/Action.php
(說明:$this->getLayout()->getUpdate()->load() 方法經過merge($handle)依次加載前幾步添加的handle,其中 Mage_Core_Model_Layout_Update getFileLayoutUpdatesXml() 等函數先一次性讀取design 包裏layout目錄下的全部啓用的.xml文件,並且確保最後讀入的是指定模板下的local.xml,因此它擁有最高優先級,能夠覆蓋默認的 handles,由今生成的是一個比較大的 packageLayout;而後fetchPackageLayoutUpdates($handle) 函數根據handles 來更新加載生成當前頁面的 pagelayout) (在Magento設計教程中說到,Magneto會根據package 和theme的 custom->default->base 層級依次讀取到相應的layout,template,skin files;laytout文件根據模塊來組織文件只是方便管理,並不嚴格要求handle必定要在某個位置。所以Magento 後臺能夠啓用Template Hints,方便設計人員找到相應的模塊的template或layout)。- 加載自定義設置中的Layout更新:$update->addUpdate($layoutUpdate) Mage_Core_Model_Layout generateXml() generateBlocks()
- 生成佈局xml文件和佈局 塊:$this->generateLayoutXml()->generateLayoutBlocks() Mage_Core_Model_Layout 的 _generateBlock() 引入template,即生成block content時從template返回了html。
- 應用自定義設置的template:$this->getLayout()->helper(‘page/layout’)->applyTemplate($settings->getPageLayout())
3. 最後控制器進行呈現: $this->renderLayout(); Mage_Core_Controller_Varien_Action。同時接收js,圖片,css等靜態文件,返回http response,輸出到瀏覽器。