日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

深入理解Magento – 第二章 – Magento請求分發(fā)

系統(tǒng) 2670 0

深入理解Magento

作者: Alan Storm
翻譯: Hailong Zhang


第二章 – Magento請求分發(fā)與控制器

Model-View-Controller (MVC) ,模型-視圖-控制器,源于Smalltalk編程語言和Xerox Parc。現(xiàn)在有很多系統(tǒng)是基于MVC架構(gòu)的,不同的系統(tǒng)MVC的實(shí)現(xiàn)也略有不同,但都體現(xiàn)了MVC的精髓,分離數(shù)據(jù),業(yè)務(wù)邏輯和顯示邏輯。最常見的 PHP MVC框架是這樣的


  1. URL請求被一個PHP文件攔截,通常稱為前端控制器(Front Controller)
  2. 這個PHP文件分析這個URL,獲得一個執(zhí)行控制器(Action Controller)的名字和一個執(zhí)行方法(Action Method)的名字,這個過程通常稱為路由(Routing)
  3. 實(shí)例化#2獲得的執(zhí)行控制器
  4. 調(diào)用執(zhí)行控制器的執(zhí)行方法
  5. 執(zhí)行方法中處理業(yè)務(wù)邏輯,比如獲取數(shù)據(jù)
  6. 執(zhí)行控制器負(fù)責(zé)把數(shù)據(jù)傳遞給顯示邏輯
  7. 顯示邏輯生成HTML

?

這個架構(gòu)相對于傳統(tǒng)的“每個php都是一個頁面”來講已經(jīng)是一個巨大的飛躍,但還是有人抱怨【譯者注: CodeIgniter 就是這樣一個MVC框架】

  • 前端控制器仍然以全局的方式運(yùn)行
  • 基于配置的慣例導(dǎo)致了系統(tǒng)不夠模塊化
    • URL Routing不夠靈活
    • 控制器往往和視圖綁定
    • 更改默認(rèn)設(shè)置往往導(dǎo)致大量的重構(gòu)

?

Magento創(chuàng)造了一個更抽象的MVC來解決上述問題。


  1. URL請求被一個PHP攔截
  2. 這個PHP文件實(shí)例化一個Magento對象
  3. Magento對象實(shí)例化前端控制器
  4. 前端控制器實(shí)例化全局配置中指定的路由對象,可以是多個
  5. 路由對象會逐個與請求URL匹配
  6. 如果發(fā)現(xiàn)匹配,那么可以獲得一個執(zhí)行控制器和一個執(zhí)行方法的名字
  7. 實(shí)例化#6獲得的執(zhí)行控制器,并調(diào)用相應(yīng)的執(zhí)行方法
  8. 執(zhí)行方法中處理業(yè)務(wù)邏輯,模型數(shù)據(jù)
  9. 控制器實(shí)例化布局對象(Layout)
  10. 布局對象根據(jù)請求的參數(shù),系統(tǒng)配置創(chuàng)建一個塊對象(Block)列表,并實(shí)例化
  11. 布局對象會調(diào)用塊對象的output方法生成HTML。這是一個遞歸的過程,因?yàn)閴K對象可以嵌套塊對象
  12. 每一個塊對象都和一個模板文件(Template File)對應(yīng)。塊對象包含了顯示邏輯,模板文件包含了HTML和PHP輸出代碼
  13. 塊對象直接從模型那里獲得數(shù)據(jù),換句話說,在Magento的MVC架構(gòu)中,控制器并不直接把數(shù)據(jù)傳給視圖

?

這里很復(fù)雜,我們以后會詳細(xì)解釋每一個部分。我們先關(guān)注“前端控制器->路由對象->執(zhí)行控制器”部分。

?

Hello World示例

我們講了太多理論,現(xiàn)在讓我們來實(shí)踐一下,通過實(shí)踐來加深理解。下面是我們將要做的事情

  1. 創(chuàng)建一個Hello World模塊
  2. 為這個模塊配置路由
  3. 為這個模塊創(chuàng)建執(zhí)行控制器


創(chuàng)建Hello World模塊

首先,我們要創(chuàng)建一個模塊的目錄結(jié)構(gòu),這個我們以前已經(jīng)做過了,就不再熬述

app/code/local/Alanstormdotcom/Helloworld/Block

app/code/local/Alanstormdotcom/Helloworld/controllers

app/code/local/Alanstormdotcom/Helloworld/etc

app/code/local/Alanstormdotcom/Helloworld/Helper

app/code/local/Alanstormdotcom/Helloworld/Model

app/code/local/Alanstormdotcom/Helloworld/sql


下面是config.xml的內(nèi)容 PATH: app/code/local/Alanstormdotcom/Helloworld/etc/config.xml

    <config>   
    <modules>
        <Alanstormdotcom_Helloworld>
            <version>0.1.0</version>
        </Alanstormdotcom_Helloworld>
    </modules>
</config>
  
?

然后我們要創(chuàng)建一個系統(tǒng)配置文件來激活這個模塊 PATH: app/etc/modules/Alanstormdotcom_Helloworld.xml

    <config>
    <modules>
        <Alanstormdotcom_Helloworld>
            <active>true</active>
            <codePool>local</codePool>
        </Alanstormdotcom_Helloworld>
    </modules>
</config>
  
?

最后,讓我們檢查一下模塊是不是已經(jīng)被激活

  1. 清空Magento緩存
  2. 在管理后臺,進(jìn)入 System->Configuration->Advanced
  3. 展開“Disable Modules Output”
  4. 確認(rèn)Alanstormdotcom_Helloworld顯示出來了


配置路由

下面,我們要配置一個路由。路由是用來把一個URL請求轉(zhuǎn)換成一個執(zhí)行控制器和方法。和傳統(tǒng)的PHP MVC不同的是,你需要在Magento的全局配置中顯式的定義你的路由。我們繼續(xù)上面的例子,在config.xml中,添加如下代碼

    <config>   
    ...
    <frontend>
        <routers>
            <helloworld>
                <use>standard</use>
                <args>
                    <module>Alanstormdotcom_Helloworld</module>
                    <frontName>helloworld</frontName>
                </args>
            </helloworld>
        </routers> 
    </frontend>
    ...
</config>
  
?

在這里,我們有很多新名詞要解釋。


什么是<frontend />?

<frontend />標(biāo)簽指向一個Magento區(qū)(Area),比如“frontend”就是指網(wǎng)站的前臺,“admin”是指網(wǎng)站的后臺,“install”是 指Magento的安裝程序。【譯者注:這個有點(diǎn)像磁盤分區(qū),區(qū)和區(qū)之間是相互獨(dú)立的,但是都?xì)w操作系統(tǒng)能夠管理,在這里歸Magento管理。默認(rèn)的 Magento安裝沒有“install”這個區(qū),frontend區(qū)接管了,全局配置中的以下代碼可以解釋這一點(diǎn)

    <frontend>
...
  <install>
    <use>standard</use>
    <args>
      <module>Mage_Install</module>
      <frontName>install</frontName>
    </args>
  </install>
...
</frontend>
  
?

什么是<routers />?

Phil Karlton有一句很著名的話“在計算機(jī)領(lǐng)域只有兩件事是困難的:緩存和命名”。Magento引入了很多新概念,無疑存在很多命名問題,這里就是一個 例子。<routers>標(biāo)簽有時候包含的是路由對象的定義,有時候包含的是路徑的定義。路由對象是進(jìn)行路由操作的實(shí)體,而路徑僅僅是路由對 象的一個參數(shù)。【譯者注: 如果你仔細(xì)看過那個全局配置xml的話,你會發(fā)現(xiàn)有兩處地方出現(xiàn)<routers>,一處是“<web> -> <routers>”,另外一處是“<frontend> -> <routers>”。你再仔細(xì)看看會發(fā)現(xiàn)兩處<routers>包含的內(nèi)容不一樣。第一處包含的是路由對象的定義,第二處包含 的是路徑的定義。】


什么是<module />?

這個標(biāo)簽的內(nèi)容應(yīng)該是一個模塊的全名,Packagename_Modulename,在這里是“Alanstormdotcom_Helloworld”。Magento用這個名字來定位你的模塊文件。


什么是<frontName />?

當(dāng)一個router解析一個URL的時候,它是按照如下規(guī)則進(jìn)行的
http://example.com/frontName/actionControllerName/actionMethod/


所以,當(dāng)我們在<frontName>標(biāo)簽里定義了“helloworld”以后,Magento會把如下的URL請求交給我們的模塊“Alanstormdotcom_Helloworld”來處理
http://example.com/helloworld/*


有些人容易把<frontName>和前端控制器(Front Controller)混淆起來。它們是兩個不同的概念,<frontName>只跟路由相關(guān)。【譯者注: 根據(jù)我們前面講過的Magento的MVC流程,前端控制器是用來實(shí)例化所有路由的,而這里的“frontName”只是路由過程中的一個參數(shù)】


什么是 <helloworld />?

這個標(biāo)簽的名字應(yīng)該是模塊名字的小寫版本。我們的模塊名字是“Helloworld”,所以這里我們用“helloworld”。你應(yīng)該也已經(jīng)注意 到我們定義的“frontName”也是和我們的模塊相匹配的。這是一個不成文的規(guī)定,但不是強(qiáng)制要求。事實(shí)上,一個模塊可以定義多 個<routers>,也就是可以有多個“frontName”。


為路由創(chuàng)建執(zhí)行控制器

還記得Magento的MVC流程嗎?路由會把控制權(quán)交給執(zhí)行控制器。上面我們定義了路由,現(xiàn)在我們來定義我們的執(zhí)行控制器。首先創(chuàng)建文件
app/code/local/Alanstormdotcom/Helloworld/controllers/IndexController.php


模塊的控制器應(yīng)該放在模塊的子目錄“controllers”(小寫c)里面。這是規(guī)定,Magento會在這個目錄尋找模塊的控制器文件。我們的第一個控制器包含以下內(nèi)容

    class Alanstormdotcom_Helloworld_IndexController extends Mage_Core_Controller_Front_Action {       
    public function indexAction() {
        echo 'Hello World!';
    }
}
  
?

清空Magento緩存,請求如下URL
http://exmaple.com/helloworld/index/index


如果你看到一個空白頁面上面寫著“Hello World”,那么恭喜你,你已經(jīng)成功創(chuàng)建了你的第一個Magento控制器!


如何命名執(zhí)行控制器?

還記得config.xml的<module>標(biāo)簽嗎?

    <module>Alanstormdotcom_Helloworld</module>
  
?

執(zhí)行控制的名字的構(gòu)成如下

  1. 以<moudule>標(biāo)簽的內(nèi)容開始 (Alanstormdotcom_Helloworld)
  2. 緊接一個下劃線 (Alanstormdotcom_Helloworld_)
  3. 加上我們給控制器取的名字“Index”(Alanstormdotcom_Helloworld_Index)
  4. 最后加上關(guān)鍵詞“Controller” (Alanstormdotcom_Helloworld_IndexController)

我們自己定義的屬于frontend區(qū)的執(zhí)行控制器都應(yīng)該繼承Mage_Core_Controller_Front_Action。


URL里面的index/index是什么意思?

正如前文所述,Magento默認(rèn)的路由的規(guī)則如下
http://example.com/frontName/actionControllerName/actionMethod/


所以在我們請求的URL
http://exmaple.com/helloworld/index/index


其中“helloworld”是“frontName”,第一個“index”是執(zhí)行控制器(Action Controller)的名字,第二個“index”是執(zhí)行方法的名字。對比我們寫的執(zhí)行控制器代碼,我們不難發(fā)現(xiàn)執(zhí)行方法的定義是執(zhí)行方法名字加上 “Action”關(guān)鍵字

    public function indexAction(){...}
  
?

Magento根據(jù)命名規(guī)則找到執(zhí)行控制器文件并實(shí)例化,然后再根據(jù)命名規(guī)則調(diào)用指定的執(zhí)行方法。如果URL沒有給出執(zhí)行控制器名字或者執(zhí)行方法,Magento會用默認(rèn)的“index”來替代,所以下面三個URL是等價的

http://exmaple.com/helloworld/index/index

http://exmaple.com/helloworld/index/

http://exmaple.com/helloworld/


我們再來看一個例子。如果URL如下
http://exmaple.com/checkout/cart/add


Magento的執(zhí)行步驟如下

  1. 查詢?nèi)峙渲茫业絝rontName “checkout”對應(yīng)的模塊,Mage_Checkout
  2. 找到執(zhí)行控制器 “Mage_Checkout_CartController”
  3. 調(diào)用執(zhí)行控制器的“addAction”方法


進(jìn)一步理解執(zhí)行控制器

下面我們來為我們的執(zhí)行控制器添加一個執(zhí)行方法。添加如下代碼到IndexController.php

    public function goodbyeAction() {
    echo 'Goodbye World!';
} 
  
?

請求URL
http://example.com/helloworld/index/goodbye


這次你應(yīng)該看到“Goodbye World!”。因?yàn)槲覀兝^承了“Mage_Core_Controller_Front_Action”,我們可以使用一些父類已經(jīng)定義好的方法和變 量。比如父類會把URL后面跟的參數(shù)轉(zhuǎn)換成key/value的數(shù)組。添加如下代碼到我們的執(zhí)行控制器

    public function paramsAction() {
    echo '<dl>';           
    foreach($this->getRequest()->getParams() as $key=>$value) {
        echo '<dt><strong>Param: </strong>'.$key.'</dt>';
        echo '<dl><strong>Value: </strong>'.$value.'</dl>';
    }
    echo '</dl>';
}
  
?

請求如下URL
http://example.com/helloworld/index/ params?foo=bar&baz=eof

或者

http://example.com/helloworld/index/params /foo/bar/baz/eof


你應(yīng)該看到如下輸出
Param: foo
? Value: bar
Param: baz
? Value: eof


最后,讓我們再寫一個執(zhí)行控制器,用來處理以下URL
http://example.com/helloworld/messages/goodbye


這里的執(zhí)行控制器名字是“messages”,所以我們要創(chuàng)建如下文件
app/code/local/Alanstormdotcom/Helloworld/controllers/MessagesController.php


執(zhí)行控制器的類名應(yīng)該是
Alanstormdotcom_Helloworld_MessagesController


添加執(zhí)行方法

    public function goodbyeAction()        
{
    echo 'Another Goodbye';
}
  
?

好了,Magento的MVC架構(gòu)大概就是這樣了。它比傳統(tǒng)的PHP MVC要復(fù)雜一點(diǎn),但是Magento的這個高度靈活的MVC架構(gòu)能讓你創(chuàng)造出幾乎所有你能想到的URL結(jié)構(gòu)。

?

?

from: http://www.zhlmmc.com/?p=587

?

?

深入理解Magento – 第二章 – Magento請求分發(fā)與控制器


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 绥滨县| 中卫市| 邻水| 民和| 习水县| 东乌| 桐庐县| 乌兰察布市| 景谷| 望城县| 元朗区| 皮山县| 内江市| 二手房| 修文县| 健康| 肇州县| 靖州| 壶关县| 贵德县| 建湖县| 金坛市| 介休市| 阿瓦提县| 双辽市| 永修县| 贵溪市| 荣成市| 八宿县| 巴彦淖尔市| 吉林市| 老河口市| 凤城市| 封开县| 大悟县| 揭东县| 大英县| 进贤县| 德格县| 灵璧县| 丹阳市|