Magento模型
Magento 理所当然的也追随潮流应用了ORM。虽然 Magento自带的 Zend框架提供了SQL 抽象层,但是在大多数情况下我们将通过 Magento自带的模型和我们自己的模型来进行数据访问。他和视图层(View)一样,Magento的模型层也不是简单的 ORM,而是一个高度灵活, 高度抽象甚至有点令人费解。
Magento的模型解剖
大部分的 Magento模型分为两类。第一类是基本的 ActiveRecord类型,一张表一个对象的模型。第二类是Entity Attribute Value(EAV)模型。【译者注:EAV翻译成“实体属性值”有点词不达意,还是就叫 EAV的好】Magento 自己定义了一个数据类型叫做模型集合 (Model Collection)。顾名思义,模型集合就是一个对象里面包含了很多模型对象。Magento 的创造者Varien团队实现了PHP类库的标准接 口,“IteratorAggregate”,“Countable”。这样模型集合就能调用这些方法,这也是模型集合和数组的区别。
Magento 的模型并不直接访问数据库。每一个模型都有一个资源模型(ResourceModel),每一个资源模型拥有两个适配器(Adapter),一个读,一个写。这样的话逻辑模型和数据库访问就分开了,所以从理论上讲更改底层数据库 只需要重写适配器就可以了,所有上层代码都不需要更改。
创建基本模型
下面我们开始创建一个基础的Magento模型,我们以简单的weblog博客为例,构建一个模型,总的分为以下几步。
- 创建一个新的“Weblog”模块
- 为magento加载该模块,在app/etc/modules下添加配置文件Magentotutorial_Weblog.xml
- 检查模块是否已加载
- 为我们的模型创建一个数据库表
- 配置Magentotutorial/Weblog/etc/config.xml
- 完善模型php文件
- 实例化模型
- helper/block
- layout/Template display
- 结束
1.新建一个新的“Weblog”模块
app |-code\ |-----local\ |----------Magentotutorial\ |--------------Weblog\ |------------------controllers\ |----IndexController.php |------------------etc\ |----config.xml |------------------Model\ |----Resource\ |----Blogpost\ |----Collection.php |----Blogpost.php |----Blogpost.php
2.为magento加载该模块,在app/etc/modules下添加配置文件Magentotutorial_Weblog.xml
<?xml version="1.0" encoding="utf-8" ?> <config> <modules> <Magentotutorial_Weblog> <active>true</active> <codePool>local</codePool> </Magentotutorial_Weblog> </modules> </config>
3.查看magento是否加载到该模块:
进入管理后他,System->Configuration->ADVANCED,查看Magentotutorial_Weblog是否为Enable
4.为我们的模型创建一个数据库表
CREATE TABLE `mag_blog_posts` ( `blogpost_id` int(11) NOT NULL AUTO_INCREMENT, `title` text, `post` text, `date` datetime DEFAULT NULL, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`blogpost_id`) ); INSERT INTO `blog_posts` VALUES (1,'My New Title','This is a blog post','2009-07-01 00:00:00','2009-07-02 23:12:30'); INSERT INTO `blog_posts` VALUES (2,'My Second Time','This is a blog post22','2019-11-01 00:10:03','2012-07-02 23:12:30');
5.配置Magentotutorial/Weblog/etc/config.xml
<?xml version="1.0" encoding="utf-8" ?> <config> <frontend> <routers> <weblog> <use>standard</use> <args> <module>Magentotutorial_Weblog</module> <frontName>weblog</frontName> </args> </weblog> </routers> </frontend> <global> <models> <weblog> <class>Magentotutorial_Weblog_Model</class> <!-- need to create our own resource, can't just use core_resource --> <resourceModel>weblog_resource</resourceModel> </weblog> <weblog_resource> <class>Magentotutorial_Weblog_Model_Resource</class> <entities> <blogpost> <table>blog_posts</table> </blogpost> </entities> </weblog_resource> </models> </global> </config>
6.完善模型php文件
Magentotutorial/Weblog/Model/Blogpost.php
class Magentotutorial_Weblog_Model_Blogpost extends Mage_Core_Model_Abstract { protected function _construct() { $this->_init('weblog/blogpost'); } }
Magentotutorial/Weblog/Model/Resource/Blogpost.php
class Magentotutorial_Weblog_Model_Resource_Blogpost extends Mage_Core_Model_Resource_Db_Abstract{ protected function _construct() { $this->_init('weblog/blogpost', 'blogpost_id'); } }
Magentotutorial/Weblog/Model/Resource/Blogpost/Collection.php
class Magentotutorial_Weblog_Model_Resource_Blogpost_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract { protected function _construct() { $this->_init('weblog/blogpost'); } }
7.实例化模型
Magentotutorial/Weblog/controllers/IndexController.php
<?php class Magentotutorial_Weblog_IndexController extends Mage_Core_Controller_Front_Action { public function testModelAction() { echo "<pre>Setup!\n"; $blogpost = Mage::getModel('weblog/blogpost'); $blogpost_coll=$blogpost->getCollection(); var_dump($blogpost_coll->getData()); $blogpostres =Mage::getResourceModel('weblog/blogpost_collection'); var_dump($blogpostres->getData()); } }
至此,简单模型已经建立,后台管理清空下缓存后,通过http://127.0.0.1/magento/weblog/index/testModel 即可访问
getModel /getResourceModel 有一定区别,请自行参考以上代码区分
如果你的代码运行有问题,请开启调试模式,点这里
以下篇章是如何将数据显示到页面的,这里先修改下Magentotutorial/Weblog/controllers/IndexController.php 文件,增加function indexAction
<?php class Magentotutorial_Weblog_IndexController extends Mage_Core_Controller_Front_Action { public function testModelAction() { echo "<pre>Setup!\n"; $blogpost = Mage::getModel('weblog/blogpost'); $blogpost_coll=$blogpost->getCollection(); var_dump($blogpost_coll->getData()); $blogpostres =Mage::getResourceModel('weblog/blogpost_collection'); var_dump($blogpostres->getData()); $this->loadLayout(); $this->renderLayout(); } public function indexAction(){ $this->loadLayout(); $this->renderLayout(); } }
8.创建好Model后,继续添加Helper和Block,在配置文件Magentotutorial/Weblog/etc/config.xml中添加
<global> <blocks> <weblog> <class>Magentotutorial_Weblog_Block</class> </weblog> </blocks> <helpers> <weblog> <class>Magentotutorial_Weblog_Helper</class> </weblog> </helpers> </global>
Magentotutorial/Weblog/Helper/Data.php
<?php class Magentotutorial_Weblog_Helper_Data extends Mage_Core_Helper_Abstract { }
Magentotutorial/Weblog/Block/Weblog.php
<?php class Magentotutorial_Weblog_Block_Weblog extends Mage_Core_Block_Template { public function blogposts() { //这里没有使用 Controller action中的模型获取数据,是为了让大家了解,亦可以使用此方式获取数据 $read = Mage::getSingleton("core/resource")->getConnection('core_read'); $sql = "select * from `mag_blog_posts`"; $result = $read->fetchAll($sql); return $result; } }
9.这里遇到的问题是,得到了数据,但是如何才能将数据传递到Template的phtml页面,TP有$this->assign(),$this->display()来传递,magento是如何传递的呢?是否想过这个问题?我也在这里卡了很久,一直在说Magento的配置文件很强大,之前一直没有体现,这里的解决方式,还是magento的配置文件。 在design/frontend/rwd/default/layout文件夹下,新建local.xml,添加如下代码:
<?xml version="1.0" encoding="UTF-8"?> <layout version="0.1.0"> <!-- IndexController ouptput config --> <weblog_index_index> <reference name="root"> <block type="weblog/weblog" name="root" output="toHtml" template="weblog/blog_post.phtml"></block> </reference> </weblog_index_index> </layout>
这里解释下含义:
weblog_index_index:表示weblog模块下的IndexController下的indexAction;
<reference>表示引入模块,name=“root”表示替换掉默认的以name=“root”的模块;
<block>表示新建一个模块, type=”weblog/weblog”,表示从weblog模块下,找block下的weblog.php文件, template=”weblog/blog_posts.phtml”,表示在Template文件夹下,找到weblog/blog_posts.phtml文件。
10.在design/frontend/rwd/default/template文件夹下新建weblog/blog_posts.phtml
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Untitled</title> <style type="text/css"> body { background-color:pink; } </style> </head> <body> <h3>blog_posts Table33399</h3> <table> <?php foreach($this->blogposts() as $r):?> <tr> <?php foreach($r as $v):?> <td><?php echo $v;?></td> <?php endforeach;?> </tr> <?php endforeach;?> </table> </body> </html>
通过http://127.0.0.1/magento/weblog/index/index 即可访问,到此为止,一个简单的模块就跑通了。