Magento是一个php电子商务系统.
内部模块化.
创建模块流程Magento系统模块
app/code/core/Mage
其中每一个子目录都是一个单独的模块
自己创建的模块放在下面路径
app/code/local/Packagename
自创的新模块应该包含以下目录结构
app/code/local/Packagename/Configviewer/Block
app/code/local/Packagename/Configviewer/cotrollers
app/code/local/Packagename/Configviewer/etc
app/code/local/Packagename/Configviewer/Helper
app/code/local/Packagename/Configviewer/Model
app/code/local/Packagename/Configviewer/sql
接下来还需要创建两个文件
一个是config.xml
app/code/local/Packagename/Configviewer/etc/config.xml
文件内容如下
<config> <modules> <Packagename_Configviewer> <version>0.1.0</version> </Packagename_Configviewer> </modules> </config>
第二个文件创建在
app/etc/modules/Packagename_Configviewer.xml
此文件命名规则"包名_模块名.xml" 即"Packagename_Modulename.xml"
文件内容如下
<config> <modules> <Packagename_Configviewer> <active>true</active> <codePool>local</codePool> </Packagename_Configviewer> </modules> </config>
先看看创建的模块有没有被加载出来:
1. 清空magento 缓存
2. 在后台管理界面, 进入System->Configuration->Advanced
3. 展开 "Disable Modules Output"
4. 确认 "Package_Configviewer" 显示出来了
如果看到 Package_configviewer 那么这个新模块创建成功.
创建模块逻辑之前只是创建了模块的骨架, 现在为这个模块输入逻辑:
1. 检查 "showConfig" 查询字符串是否存在
2. 检查 "showConfig" 存在, 那么检查 "showConfigFormat" 查询字符串是否存在
3. 如果 "showConfigFormat" 存在, 那么输出指定格式的配置信息 否则输出默认格式的配置信息
4. 终止执行流程
首先config.xml文件需要修改
<config> <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> </config>
然后创建如下文件
Packagename/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
显示出来的页面是巨大的XML文件, 描述了系统状态, 列出所有的模块, 数据类型, 类, 事件, 监听器, Magento会解析每个模块的config.xml, 并把他包含在这个全局配置中.
一般PHP实例化一个类是这样的:
$helper_salesrule = new Mage_Salesrule_Helper();
Magento抽象了PHP的实例化模式, 在Magento中, 上面的代码等同于
$helper_salesrule = Mage::helper('salesrule');
Magento按照以下逻辑处理:
1. 在配置文件中查找<helpers />标签
2. 在<helpers />中查找 <salesrule />标签
3. 在<salesrule /> 中查找class
4. 实例化从#3中找到的类(Mage_Salesrule_Helper)
这样看起来有些麻烦, 但好处是我们不需要更改Magento的代码就可以更改Magento的核心功能.
MVC流程:
1. URL请求被一个PHP文件拦截, 通常称为前端控制器(Front Controller)
2. 这个PHP文件分析URL, 获得一个执行控制器的名字(Action Controller)和一个执行方法(Action Method)的名字, 这个过程通常称为路由(Routing)
3. 实例化#2获得的执行控制器
4. 调用执行控制器的执行方法
5. 执行方法中处理业务逻辑, 比如获取数据
6. 执行控制器负责把数据传给显示逻辑
7. 显示逻辑生成HTML
Magento的MVC流程和这个不同:
1. URL请求被一个PHP文件拦截
2. 这个PHP文件实例化一个Magento对象
3. Magento对象实例化前端控制器
4. 前端控制器实例化全局配置中指定的路由对象, 可以是多个
5. 路由对象会逐个与请求URL匹配
6. 如果发现匹配, 那么可以获得一个执行控制器和执行方法的名字
7. 实例化#6获得的执行控制器并调用相应的执行方法
8. 执行方法中 处理业务逻辑, 数据模型
9. 控制器实例化布局对象(Layout)
10. 布局对象根据请求的参数, 系统配置创建一个块对象(Block)列表, 并实例化
11. 布局对象会调用块对象的output方法生成HTML. 这是一个递归的过程, 因为块对象可以嵌套块对象
12. 每一个块对象和一个模板文件(Template File)对应, 块对象包含了显示逻辑, 模版文件包含了HTML和PHP代码输出
13. 块对象直接从模型那里获取数据, 也就是说 Magento 的MVC 架构中, 控制器不直接把数据传给视图
创建Hello World模块创建一个模块的目录结构
app/code/local/Test/Helloworld/Block
app/code/local/Test/Helloworld/controllers
app/code/local/Test/Helloworld/etc
app/code/local/Test/Helloworld/Helper
app/code/local/Test/Helloworld/Model
app/code/local/Test/Helloworld/sql
下面是 config.xml 的内容
PATH: app/code/local/Alanstormdotcom/Helloworld/etc/config.xml
<config>
<modules>
<Test_Helloworld>
<version>0.1.0</version>
</Test_Helloworld>
</modules>
</config>
然后我们要创建一个系统配置文件来激活这个模块 PATH: app/etc/modules/Test_Helloworld.xml <config> <modules> <Test_Helloworld> <active>true</active> <codePool>local</codePool> </Test_Helloworld> </modules> </config>
然后看看模块是否被激活
1. 清空Magento缓存
2. 在管理后台进入 System->Configuration->Advanced
3. 展开 Disable Modules Output
4. 确认Test_Helloworld显示出来了
配置路由Magento定义路由是在config.xml中, 完善etc下面的config.xml, 增加路由信息
<?xml version="1.0" ?> <config> <modules> <Test_Helloworld> <version>0.1.0</version> </Test_Helloworld> </modules> <frontend> <routers> <helloworld> <use>standard</use> <args> <module>Test_Helloworld</module> <frontName>helloworld</frontName> </args> </helloworld> </routers> </frontend> </config>
其中frontName是路由URL的名字
为路由创建执行控制器
首先创建文件 app/code/local/Test/Helloworld/controllers/IndexController. php
class Test_Helloworld_IndexController extends Mage_Core_Controller_Front_Action { public function indexAction() { echo 'Hello World!'; } }
清空缓存, 如果显示Hello world则运行正常
这个遇到一个问题搞了好久, 按照教程页面显示404, 然后加上index.php才解决
http://www.magento1800.com/index.php/helloworld/index/index
执行控制的名字构成如下
1. 以<module>标签的内容开始(Test_Helloworld)
2. 接下来一个下划线 (Test_Helloworld_)
3. 加上我们给控制器取得名字"Index" (Test_Helloworld_Index)
4. 最后加上关键词"Controller" (Test_Helloworld_IndexController)
我们自己定义的属于frontend区的执行控制器都应该继承Mage_Core_Controller_Front_Action
URL里面的index/index是什么意思Magento的默认路由规则如下
http://www.magento1800.com/frontName/actionControllerName/actionMethod
所以我们之前的请求URL
http://www.magento1800.com/helloworld/index/index
下面3个URL是等价的
http://www.magento1800.com/helloworld/index/index
http://www.magento1800.com/helloworld/index/
http://www.magento1800.com/helloworld/
如果URL如下
http://www.magento1800.com/checkout/cart/add
Magento执行步骤如下
1. 查询全局配置, 找到frontName"checkout"对应的模块, Mage_Checkout
2. 找到执行控制器 "Mage_Checkout_CartController"
3. 调用执行控制器"addAction"方法
进一步理解执行控制器
下面我们为我们的执行控制器添加一个执行方法. 添加如下代码到IndexController.php
public function goodbyeAction() { echo 'Goodbye World'!; }
因为我们继承了 “Mage_Core_Controller_Front_Action”,我们可以使用一些父类已经定义好 的方法和变 量。比如父类会把 URL 后面跟的参数转换成 key/value 的数组。添 加如下代码到我们的执行控制器
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://www.magento1800.com/index.php/helloworld/index/params?aaa=11&bbb=22
你应该看到如下输出
Param: aaaValue: 11Param: bbbValue: 22
最后,让我们再写一个执行控制器,用来处理以下 URL
http://www.magento1800.com/index.php/helloworld/messages/goodbye
布局, 块和模板一般的MVC架构是控制器controller传数据给视图view文件, 但是Magento里面是直接引用模型, 从模型取数据, 这样设计就导致了视图被拆分成块Block和模板Template. 块是PHP对象, 模版是原始PHP文件, 混合了HTML和PHP代码, 每一个块都和一个唯一模板文件绑定. 在模版文件PHTML中, $this就是指该模板文件对应的块对象.
嵌套块
Magento可以在块中嵌套块.
布局对象
创建和启用模型
创建模型有以下四个步骤:
1. 启用模型
2. 启用资源模型
3. 在资源模型中添加实体, 对于简单的模型来说, 实体就是数据表的名字
4. 为资源模型设置读,写适配器
假如这些已经设置好了, 那么如何使用呢, Magento中用以下方式来实例化一个模型
$model = Mage::getModel('helloworld/blogpost');
启用模型
修改模块的config.xml
<global> <!-- ... --> <models> <helloworld> <class>Zhlmmc_Helloworld_Model</class> <!-- need to create our own resource, can't just use core_mysql4 --> <resourceModel>helloworld_mysql4</resourceModel> </helloworld> </models> <!-- ... --> </global>
在模块文件夹里创建这个类
File: app/code/local/Test/Helloworld/Model/Blogpost.php class zhlmmc_helloworld_Model_Blogpost exitends Mage_Core_Model_Abstract { protected function _construct() { $this->_init('helloworld/blogpost'); } }
其中_construct不是PHP的构造函数__constract, 而是应该调用父类已经定义好的'_init'fangfa , 参数是资源模型URI.
启用资源模型并添加实体
下面我们要为模型设置资源模型. 资源模型才是真正和数据库对话的组建. 在模型配置中:
<resourceModel>helloworld_mysql4</resourceModel>
我们不需要显示的调用资源模型那个, 但是当一个模型需要访问数据库的时候, Magento会自动实例化一个资源模型来使用
Mage::getResourceModel('helloworld/blogpost')
这里的helloworld/blogpost就是我们给模型的_init传入的参数
需要在config.xml中添加资源模型的声明
<global> <!-- ... --> <models> <!-- ... --> <helloworld_mysql4>
<class>Zhlmmc_Helloworld_Model_Resource_Mysql4</class>
</helloworld_mysql4> </models> </global>
=======================================
Magento 1.8.0.0安装的几个坑, 安装了4次才搞定.
首先PHP.INI执行最大时间设置成3600, 因为创建数据库过程很慢.
其次为127.0.0.1设置viturehost, 指向一个自定义域名, 再把这个域名配置到自己的hosts里面, 因为Magento有些配置只认域名.
然后安装之前改下面2个地方
复制magento根目录下 /errors/local.xml.sample 并命名为/errors/local.xml 改变magento根目录下/lib/Zend/Cache/Backend/File.php 文件里面 protected $_options = array( 'cache_dir' => NULL, 'file_locking' => true, 为 protected $_options = array( 'cache_dir' => 'tmp/', 'file_locking' => true, 然后在根目录下创建tmp文件夹.