天天看点

magento开发 -- 深入理解Magento

作者:alan storm

翻译:zhlmmc

我从2007年开始使用magento,应该算是国内第一批使用magento的用户。但是我却从来没有认真研究过magento,更多的停留在应用层面。虽然也做过一些插件,但也就是依葫芦画瓢而已。偶然间看到alan storm的一系列关于magento的文章,我忍不住的心潮澎湃,相见恨晚。alan的文章循序渐进,深入浅出地讲述了magento的架构和工作方式, 把一个复杂系统的内部结构淋漓尽致的展现在我们面前。读完以后,我茅塞顿开,感叹magento的强大,架构之美。于是我决定翻译alan的文章,希望对更多的magento开发者有所帮助。

alan的文章不是magento入门教程,并不是教你如何安装,使用magento。借用 alan的原话“magento articles for professional developers”,我认为这里的“professional”包含以下几点:

懂得php的运作方式

良好的编程基础 (写过5w行代码以上)

了解基本设计模式

安装并使用过magento

阅读并修改过magento代码

我的翻译加入了我自己的理解,对原文有所修改和调整。还有,alan的文章写的比较早,现在magento出新版了,所以我对文中的代码进行了修改,我翻译以后的文章是基于magento 1.4.0.1版本的。所以如果你发现我的翻译和原文有不符的地方,请不要见怪。下面让我们开始奇妙的magento之旅!

magento的配置系统就像是magento的心脏,支撑着magento的运行。这套配置系统掌管着几乎所有“module/model/class/template/etc”。它把整个magento系统抽象出来,用一个配置文件来描述。这里的“配置文件”并不是一个物理上存在的文件,而是magento根据当前的系统状态动态生成的一段xml。大多数的php开发者并不习惯于这样抽象层,因为它增加的编程的复杂性。但是这样的抽象提供了无与伦比的灵活性,允许你覆盖几乎任何系统的默认行为。

首先,让我们写一个简单的插件来看看这个所谓的“配置文件”长什么样。虽然我已经提供的现成的代码,但是还是建议你自己建立这个插件,把整个流程走一遍有助于你的理解。

我们将要创建一个magento的模块【译者注: magento的插件不叫plug-in,叫module,翻译成模块】。magento的模块由php和xml文件组成,目的是扩展或者覆盖系统的行为,比如为订单增加数据模型,更改一个类的方法,或者增加一个全新的功能。【译者注:magento自带的那些功能也都是基于模块的,比如用户注册,商品展示,结账流程等等。magento给我的感觉就是一切皆模块,和eclipse的插件体系结构有点像】

大多数magento的系统模块的结构和我们将要构建的插件的结构是一样的。magento的系统模块在以下目录

app/code/core/mage

每一个子目录都是一个单独的模块。这些模块是由magento官方开发的。我们安装完magento以后,所使用的功能就是来自这些模块。我们自己创建的模块应该放在如下目录

app/code/local/packagename

“packagename”应该是一个唯一的字符串,用来标识你的代码。通常人们使用公司名字作为packagename,比如

app/code/local/microsoft

由于我在做我自己的magento项目,我将使用我自己的域名“alanstormdotcom”。 然后,我们要创建以下目录结构

app/code/local/alanstormdotcom/configviewer/block

app/code/local/alanstormdotcom/configviewer/controllers

app/code/local/alanstormdotcom/configviewer/etc

app/code/local/alanstormdotcom/configviewer/helper

app/code/local/alanstormdotcom/configviewer/model

app/code/local/alanstormdotcom/configviewer/sql

你的插件并不一定需要包含以上所有的目录,但是为了以后开发方便,我们还是在一开始就把目录创建好。接下来我们要创建两个文件,一个是config.xml,放在etc目录下面

app/code/local/alanstormdotcom/configviewer/etc/config.xml

文件内容如下

<config>

<modules>

<alanstormdotcom_configviewer>

<version>0.1.0</version>

</alanstormdotcom_configviewer>

</modules>

</config> 

第二个文件需要在如下位置创建

app/etc/modules/alanstormdotcom_configviewer.xml

第二个文件应该遵循如下命名规则“packagename_modulename.xml”,文件内容如下

<active>true</active>

<codepool>local</codepool>

我们先不管这些文件是干什么的,以后会解释。建立好这两个文件以后,你的模块的骨架就已经完成了。magento已经知道你的模块存在,但是现在你的模块不会做任何事情。我们来确认一下magento确实装载了你的模块

清空magento缓存

在后台管理界面,进入 system->configuration->advanced

展开“disable modules output”

确认“alanstormdotcom_configviewer”显示出来了

如果你看到“alanstormdotcom_configviewer”,那么恭喜你,你已经成功创建了你第一个magento模块!

我们之前创建的模块不会做任何事情,下面我们来为这个模块加入逻辑

1. 检查“showconfig”查询字符串是否存在

2. 如果“showconfig”存在,那么检查“showconfigformat”查询字符串是否存在

3. 如果“showconfigformat”存在,那么输出指定格式的配置信息,否则输出默认格式的配置信息

4. 终止执行流程

首先更改我们的config.xml文件

<modules>...</modules>

<global>

<events>

<controller_front_init_routers>

<observers>

<alanstormdotcom_configviewer_model_observer>

<type>singleton</type>

<class>alanstormdotcom_configviewer_model_observer</class>

<method>checkforconfigrequest</method>

</alanstormdotcom_configviewer_model_observer>

</observers>

</controller_front_init_routers>

</events>

</global>

然后创建如下文件

alanstormdotcom/configviewer/model/observer.php

输入以下内容

<?php

class alanstormdotcom_configviewer_model_observer {

const flag_show_config = 'showconfig';

const flag_show_config_format = 'showconfigformat';

private $request;

public function checkforconfigrequest($observer) {

$this->request = $observer->getevent()->getdata('front')->getrequest();

if($this->request->{self::flag_show_config} === 'true'){

$this->setheader();

$this->outputconfig();

}

private function setheader() {

$format = isset($this->request->{self::flag_show_config_format}) ?

$this->request->{self::flag_show_config_format} : 'xml';

switch($format){

case 'text':

header("content-type: text/plain");

break;

default:

header("content-type: text/xml");

private function outputconfig() {

die(mage::app()->getconfig()->getnode()->asxml());

?> 

好了,代码编辑结束。清空你的magento缓存,输入如下url

http://magento.example.com/?showconfig=true

【译者注: 根据文中的配置,不难看出任何指向magento的url加了“?showconfig=true”以后,都会输出同样的内容,正常的执行流程会被终止。】

打开上述url,你应该看到一个巨大的xml文件。这个文件描述了当前magento系统的状态。它列出了所有的模块,数据模型,类,事件,监听器等等。举个例子,如果你搜索如下字符串

configviewer_model_observer

你会发现刚刚你创建的那个类被列出来了。magento会解析每个模块的config.xml,并把它们包含在这个全局配置中。

到目前为止,我们所作的事情似乎没什么意义,但是这个配置文件却是理解magento的关键因素。你创建的每一个模块都会被加到这个配置文件中,任何时候,你需要调用一个系统功能的时候,magento都会通过这个配置文件来查询相应的模块和功能。举个简单的例子,如果你懂mvc的话,你应该和“helper class”之类概念的打过交道

$helper_salesrule = new mage_salesrule_helper();

magento抽象了php的类声明方式。在magento系统中,上面的代码等同于

$helper_salesrule = mage::helper('salesrule');

magento将通过以下逻辑来处理这行代码

在配置文件中查找<helpers />标签

在<helpers />里面查找 <salesrule />标签

在<sales />里面查找 <class />标签

实例化从#3找到的类(mage_salesrule_helper)

magento总是通过配置文件来获得类名,这个逻辑看起来有些复杂,但这样做的优点也很明显,我们可以不需要更改magento的代码就能更改magento的核心功能。【译者注: 在这个例子中,我们可以通过修改配置文件用我们自己的salesrule_helper类来替换原来那个】这种高度抽象的编程方式在php中并不常见,但是它可以让你清晰的扩展或者替换系统的某一部分。

源文:http://www.oschina.net/bbs/thread/7937?lp=1