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 即可访问,到此为止,一个简单的模块就跑通了。