你现在的位置:首页 > PHP网站建设知识库 > magento > 正文

magento模块开发教程

The Model-View-Controller MVC架构其源头可追溯到Smlltalk编程语言和Xerox Parc.从那时开始就有很多系统把他们的架构描述成MVC架构。每个系统都会有轻微的不同,but all have the goal of separating data access, business logic, and user-interface code from one another.

大部分PHP MVC框架结构都有下列特性:
URL会被一个PHP文件拦截(通常叫做前端控制器)
前端控制器会检查URL路径,导出一个控制器名和一个动作名(这个过程常叫做路由routing)
获得的控制器是实例化了的
该控制器中,与从URL里获取的动作名一致的方法会被调用
根据不同的请求变量,这个动作方法将实例化并调用方法模型。
该动作方法从模型中获取到数据,这些获取的信息会被传递到视图中
使用从数据结构中获取到的信息,视图输出HTML代码

一个PHP文件对应一个页面,MVC框架虽然已经是一个大的飞跃,但是对于一些软件工程师来说,它仍旧有一些不如意的地方:
前端控制器PHP文件仍然在全局命名空间中运行
约定性的框架导致更少的模块性
          ·URL路由选择不灵活
          ·控制器常被特定的视图绑定
          ·即使该系统拥有重写核心代码的功能,程序员依然只能在无尽的重构中编写代码

Magento团队创造了一个更为抽象的MVC模式,如下:
URL会被一个PHP文件拦截
改PHP文件将实例化一个Magento应用
Magento应用会实例化一个前端控制器对象
前端控制器会实例化许多的路由对象(特别是全局配置)
路由会检查请求的URL地址,做出相应的匹配
如果匹配成功,动作控制器和动作会被分发
动作控制器会被实例化,与动作名匹配的方法名会被调用
被调用的方法根据请求的类型,对相应的模型调用相应的方法以获取数据
动作控制器之后会实例化布局对象
根据请求变量及系统属性(大家所熟知的句柄),布局对象会为该请求创建一系列的Block对象
布局还会在相应的Block对象中调用输出方法,开始套嵌输出(Blocks之间的套嵌)
每个Block都有一个对应的模版文件。Blocks包含PHP逻辑代码,模版文件包含HTML和PHP输出代码。
Block从模型中获取相关数据,换句话说,控制器并不用来传递数据到视图中

我们最终都会接触请求的每一部分,但是现在我们需要关心的是 Front Controller -> Routers -> Action Controller部分。

Hello World

开始讲Hello World,接下来是:
在Magento系统中创建一个Hello World模块
配置这个模块的路由规则
用路由创建动作控制器

创建Hello World 模块

首先我们为这个模块创建一个目录结构,如下:
app/code/local/Magentotutorial/Helloworld/Block
app/code/local/Magentotutorial/Helloworld/controllers
app/code/local/Magentotutorial/Helloworld/etc   
app/code/local/Magentotutorial/Helloworld/Helper
app/code/local/Magentotutorial/Helloworld/Model
app/code/local/Magentotutorial/Helloworld/sql

然后为这个模块配置文件(路径是:app/code/local/Magentotutorial/Helloworld/etc/config.xml)
<config>    
    <modules>
        <Magentotutorial_Helloworld>
            <version>0.1.0</version>
        </Magentotutorial_Helloworld>
    </modules>
</config>

之后创建一个文件去激活这个模块(路径:app/etc/modules/Magentotutorial_Helloworld.xml)
<config>
    <modules>
        <Magentotutorial_Helloworld>
            <active>true</active>
            <codePool>local</codePool>
        </Magentotutorial_Helloworld>
    </modules>
</config>

最后,我们要确保这个模块被激活:
清理Magento缓存
在Magento Admin,点击System->Configuration->Advanced.
展开"Disable Modules Output"
确保Magentotutorial_Helloworld出现

配置路由规则

接下来,我们需要配置路由规则。路由会将一个URL分发到一个动作控制器和它的方法上。不像其它约定型的PHP MVC系统,在Magento中,你需要明确的在全局Magento配置中去配置路由规则。

在你的config.xml文件中,添加如下内容:
<config>    
    ...
    <frontend>
        <routers>
            <helloworld>
                <use>standard</use>
                <args>
                    <module>Magentotutorial_Helloworld</module>
                    <frontName>helloworld</frontName>
                </args>
            </helloworld>
        </routers>  
    </frontend>
    ...
</config>

这里出现了一些新的术语。先解释一下。

什么是前端 ?What is a <frontend>?

前端标签指的是一个Magento Area。你可以把Areas看作是独立的Magento应用。前台Area是一个公众的在前面的Magento购物车应用。admin Area是一个私人的管理控制台应用程序。install Area 就是安装Magento的应用。

如果配置单独的路由规则为什么是 路由 标签呢?Why a <routers> tags if we're configuring individual routes?

这里是 Phil Karlton一段计算机的著名引用:
“在计算机科学上有两个是最难的,一是缓存无效,一是命名”(大概是这样子吧 "There are only two hard things in Computer Science: cache invalidation and naming things")

和许多大的系统一样,Magento同样也备受命名的困扰。从总的系统全局配置文件中,你可以发现很多的约定名称看起来不直观且模棱两可的。<routers>标签就是其中之一。<routers>标签通常会包括关于路由规则的配置信息,有时候又会包含实际的路由对象的配置信息。这种命名方式初看的时候可能会觉得很不直观,但随着你对Magento不断深入的学习时,你会还是改变对其的看法的(Trust Me!)

什么是<frontName>

当路由解析URL地址时,会将URL分为以下几个部分:
http://example.com/frontName/actionControllerName/actionMethod/

通过在 <frontName>标签中定义 "helloworld"值,Magento就能够响应所有以下列URL访问的地址
http://example.com/helloworld/*

许多刚接触到Magento的开发者会把 frontName和前端控制器对象搞混淆。他们是不同的。FrontName只属于路由。

<hellowolrd>标签的作用

<helloworld>标签必须是模块名的小写版本。比如我们的模块名是Helloworld,那么该标签就应该是helloworld。从学术上来说这个标签规定了我们的路由命名。
你或许也注意到了<frontName>标签中的值与模块名一致,这其实是一个不成文的规定,但不是必须一致。这样的命名其实是为了避免产生命名冲突。

<module>Magentotutorial_Helloworld</module>作用

该标签必须是模块的全称,包括它的package/namespace name。这样的话系统就可以准确定位你的控制器文件(Controller filers).

创建动作控制器

完成上述配置文件之后,接下来就是 动作控制器(Action Controller),在下面路径创建:
app/code/local/Magentotutorial/Helloworld/controllers/IndexController.php

包含以下内容:
class Magentotutorial_Helloworld_IndexController extends Mage_Core_Controller_Front_Action {        

    public function indexAction() {

        echo 'Hello Index!';

    }

}

清配置缓存,载入下面URL
http://exmaple.com/helloworld/index/index

也可载入系列URL
http://exmaple.com/helloworld/index/
http://exmaple.com/helloworld/

你将会看到一个“Hello World”的空白页面。出现这样的情况,就说明我们的第一个Magento控制器已经创建成功!

Where do Action Controllers go?

Action Controllers 动作控制器应该放在模块controllers文件夹中(小写的c哦),系统就会在这里找到动作控制器。

动作控制器命名

还记得config.xml中<module>标签吧?
<module>Magentotutorial_Helloworld</module>

动作控制器命名要遵循下列规则:
1.Start with this string specified in config.xml (Magentotutorial_Helloworld)
2.接着一个下划线(Magentotutorial_Helloworld)
3.紧跟着控制器的名字(Magentotutorial_Helloworld_Index)
4.最后,加上"Controller"(Magentotutorial_Helloworld_IndexController)

所有的动作控制器都是继承 Mage_Core_Controller_Front_Action 的类。

什么是Index/index nonsense?

正如之前提到的,Magento URLs(默认)按照下列路径解析:
http://example.com/frontName/actionControllerName/actionMethod/

URL:
http://example.com/helloworld/index/index

URL中"helloworld"部分是frontname,紧跟着两个index(分别是调用的控制器和方法名),即调用helloworld模块中的IndexController控制器中的indexAction方法。

如果URL是不完整的,Magento默认使用"index",下面两个URL所访问的页面是一样的:
http://example.com/helloworld/index
http://example.com/helloworld

如果访问的URL如下:
http://example.com/checkout/cart/add

Magento将会如下操作:
1.在全局配置文件中找到使用frontName为checkout的模块(Mage_Checkout)
2.找到cart动作控制器(Mage_Checkout_CartController)
3.调用cart动作控制器下的 addAction方法

Other Action Controller Tricks
我们来创建一个非默认non-default 方法到动作控制器中,添加下列代码到IndexController.php
public function goodbyeAction() {
    echo 'Goodbye World!';
}

我们访问的下面URL测试一下:
http://example.com/helloworld/index/goodbye

因为我们扩展了Mage_Core_Controller_Front_Action的类,有些方法就可以直接使用了。例如,additional URL elements are automatically parsed into key/value pairs for us。将下列方法添加到动作控制器中:
public function paramsAction() {
    echo '<dl>';            
    foreach($this->getRequest()->getParams() as $key=>$value) {
        echo '<dt><strong>Param: </strong>'.$key.'</dt>';
        echo '<dt><strong>Value: </strong>'.$value.'</dt>';
    }
    echo '</dl>';
}

然后访问下面URL:
http://example.com/helloworld/index/params?foo=bar&baz=eof

你会看到每个参数和值(parameter and value)

最后,对于下面一个URL,系统该怎么响应呢?
http://example.com/helloworld/messages/goodbye

这里动作控制器的名字是messages,所以我们需要在下面路径中创建一个文件:
app/code/local/Magentotutorial/Helloworld/controllers/MessagesController.php

这个控制器命名就是Magentotutorial_Helloworld_MessageController,这个控制器如下:
public function goodbyeAction()         
{
    echo 'Another Goodbye';
}

对于本节已经结束。虽然相对于PHP MVC框架要复杂,但是它的高度灵活可扩展的系统却可以使我们建立我们想要的URL结构。