Magento Model设计分析(非EAV)

Magento Model是Magento中非常重要的一块,充当MVC结构中的M.他分为值model(值对象),资源model,资源Collection Model三种。一般model请参考<<设计模式在Magento中的应用–ActiveRecord>>,资源model,资源Collection Model分为一般的和基于EAV模型的两种,下面我们讨论是基于一般的。
请参考图1: model_fun

类图请参考图2: model_class

图2中每一种颜色代表图1种的一个泳道。

下面我们以Magento下自带的cms page这个功能对Model的应用来解析Magento model的设计.

我在此列出cms page功能所需要的xml配置文件,在cms/etc/config.xml里。
代码块1:

[xml]
<models>
<cms>
<class>Mage_Cms_Model</class>
<resourceModel>cms_mysql4</resourceModel>
</cms>
<cms_mysql4>
<class>Mage_Cms_Model_Mysql4</class>
<entities>
<page>
<table>cms_page</table>
</page>
<page_store>
<table>cms_page_store</table>
</page_store>
<block>
<table>cms_block</table>
</block>
<block_store>
<table>cms_block_store</table>
</block_store>
</entities>
</cms_mysql4>
</models>
[/xml]


在外界(controller中的action、block、helper),使用model,一般都是从使用值model开始,从值model中可以得到资源model和资源Collection Model.图1中第一个泳道代表值model他有两个类变量分别指向资源model和资源Collection Model.

一、值model

得到Page Model值对象,解决图1中的第一个泳道(值model)中的1,2,3
请看如一代码:代码块2

[php]$model = Mage::getModel(‘cms/page’);[/php]


请参考<<设计模式在Magento中的应用–工厂>>
以/为分隔线,把cms/page分成两个参数,一个为cms,一个为page.Magento根据cms在代码块1中的xml中找到models/cms下这个节点,然后找到class节点,并得到此节点的值Mage_Cms_Model加上page形成Mage_Cms_Model_Page(把page第一个字母大写),就是这个值model的类名。Magento使用new Mage_Cms_Model_Page()返回此model的对象,下面我们就进入了Mage_Cms_Model_Page的构造方法,爷爷类Varien_Object的构造方法是一个模板方法,将调用Mage_Cms_Model_Page中的_construct()方法,如下:
代码块3:

[php]
protected function _construct()
{
$this->_init(‘cms/page’);
}
[/php]


将调用父Mage_Core_Model_Abstract中的_init方法。他的参数值是cms/page.记住这个cms/page与上面的getModel方法与的cms/page的值虽然是一样的,但是他们的意义完全不同,_init方法中的cms/page指资源model的名称,他表示我们怎样找到这个资源model,而getModel中的cms/page表示值model的名称,他表示我们怎样去找到这个值model,他们的/前面部份cms必须相同,但是/后面部份不一定相同,分别表示资源model类名的一部份(后面部份)和值model类名的一部份(后面一部份),只不过在此碰上了,刚好相同。Magento有很多都是相同的,但是要理解好这两个参数代表不同的意义,并且/后面部份可以是不相同的.
代码块4:

[php]
protected function _init($resourceModel)
{
$this->_setResourceModel($resourceModel);
}
[/php]


将调用本类的_setResourceModel 方法
代码块5:

[php]
protected function _setResourceModel($resourceName, $resourceCollectionName=null)
{
$this->_resourceName = $resourceName;
if (is_null($resourceCollectionName)) {
$resourceCollectionName = $resourceName.’_collection’;
}
$this->_resourceCollectionName = $resourceCollectionName;
}
[/php]


第3行把传过来的资源model的指示名给类变量_resourceName,供后继使用,如果没有第二个参数(我们这里是没有传的),将在_resourceName后加一个_collection作为资源Collection Model的指示名,这里_resourceName和_resourceCollectionName分别为cms/page和cms/page_collection.
注意在Magento中,一般都没有传第二个参数$resourceCollectionName,从而使得我们的资源Collection Model的类名都是Collection,从这个方法您可可能看出,这个不是必须的,你可以改变资源Collection Model的标示,这个是不对的,因为我们的_init方法根本没有机会给我们传入这个参数.所以目前为上,我们的资源Collection Model类名都为Collection.

值model中重要的方法,解决图1中的第一个泳道(值model)中的4

1、CRUD

CU(Create/Update),由save方法实现,此方法无参数。此方法是一典型的模板方法,子类可以(用户自定义的model)实现_beforeSave/_afterSave进行一些保存数据之前的前置处理工作和后置处理工作。 save方法将调用资源model类的对象来执行事务和保存数据,本身并不处理真正的数据库操作逻辑,是新增数据或者修改数据由值model对象中的id域是否有值决定。

D(Delete),删除本对象,此方法无参数。是一典型的模板方法,子类可以(用户自定义的model)实现_beforeDelete/_afterDelete进行一些删除此行数据之前的前置处理工作和后置处理工作。delete方法将调用资源model类的对象来执行事务和数据删除,本身并不处理真正的数据库操作逻辑。

R(查找),load,此方法有两个参数,第一个参数为值,第二个参数是此值的数据表中的字段名,默认为空,表示id字段(在资源model中将进行设置),此方法是一典型的模板方法,在加载数据之后,子类可以(用户自定义的model)实现_afterLoad做一些后置处理工作.此方法填充当前对象,一般只对满足返回只有一条记录的情况。如$model = Mage::getModel(‘cms/page’)->load(1) 或者$model = Mage::getModel(‘cms/page’)->load(‘no-route’,'identifier’);

2、资源model和资源Collection model相关

得到资源model对象:
代码块6:

[php]
public function getResource()
{
return $this->_getResource();
}
protected function _getResource()
{
if (empty($this->_resourceName)) {
Mage::throwException(Mage::helper(‘core’)->__(‘Resource is not set’));
}
return Mage::getResourceSingleton($this->_resourceName);
}
[/php]


getResource 一般提供给外界使用,而_getResource提供给自己或者子类使用。我们重点分析11代码Mage::getResourceSingleton($this->_resourceName),请参考<<设计模式在Magento中的应用–工厂>>.这里我们的值是cms/page.
根据cms我们可以在代码块1中找到models/cms下的resourceModel节点,从而可以得到它的值cms_mysql4,从而可以找到models/cms_mysql4节点,并找到class节点,得到它的值是:Mage_Cms_Model_Mysql4,再加上/后的page得到此资源类名为:Mage_Cms_Model_Mysql4_Page(第一个字母大写),Magento使用new Mage_Cms_Model_Mysql4_Page()得到一个资源model对象返回。记住资源model是一个无状态对象,所以在系统中只要使用一个就可以了,所以这里使用getResourceSingleton方法。等下我们再来分析Mage_Cms_Model_Mysql4_Page的初始化.

得到资源Collection model对象:
代码块7:

[php]
public function getResourceCollection()
{
if (empty($this->_resourceCollectionName)) {
Mage::throwException(Mage::helper(‘core’)->__(‘Model collection resource name is not defined’));
}
return Mage::getResourceModel($this->_resourceCollectionName, $this->_getResource());
}
[/php]


这个方法主要提供给外界使用,这里代码重点是6行,这里使用Mage::getResourceModel方法,并把资源model对象传递给资源Collection model.请参考<<设计模式在Magento中的应用–工厂>>,这里我们的_resourceCollectionName是cms/page_collection,根据cms我们可以在代码块1中找到models/cms下的resourceModel节点,从而可以得到它的值cms_mysql4,从而可以找到 models/cms_mysql4节点,并找到class节点,得到它的值是:Mage_Cms_Model_Mysql4,再加上/后的page_collection得到 此资源类名为:Mage_Cms_Model_Mysql4_Page_Collection(第一个字母大写),Magento使用newMage_Cms_Model_Mysql4_Page_Collection ()得到一个资源Collection model对象返回。记住资源Collection model对象是有状态的对象,所以系统使用了getResourceModel方法.等下我们再来分析Mage_Cms_Model_Mysql4_Page_Collection的初始化.

根据以下的分析,我们知道了值model对象持有资源model和资源Collection model,他们的目录结构如下:

cms_model

最底下那个Page.php为值model,中间那个为资源model,最上层那个为资源Collection model
我们再次总结一下:要得到一个值model对象,可以使用如:

$model = Mage::getModel(‘cms/page’);
这里的参数,如cms/page指怎样到找到这个值model类,在值model类中的_init方法的参数,如cms/page用来指定怎样找到资源model类,同时将产生cms/page_collection用来指定怎样找到资源Collection model类。

二、资源model

资源model的初始化(解决图一中第二个泳道资源model中的1、2)

我们从后台保存一个cms page开始分析资源model的初始化:
Mage_Adminhtml_Cms_PageController 类中的saveAction方法中的几行主要代码:
代码块8:

[php]
$data = $this->getRequest()->getPost();
$model = Mage::getModel(‘cms/page’);
$model->setData($data);
$model->save();
[/php]


第1行用来得到用户提交的数据,第2行在上面的分析中以讲解过,主要是得到一个page值model对象,第3行,把数据传给值model,注意页面域的命名规范,他必须与数据库中字段的命名一致。第三行用来保存数据,很简单吧。但是save方法的分析并不简单。呵呵。
值Model中(Mage_Core_Model_Abstract)的save方法:
代码块9:

[php]
public function save()
{
$this->_getResource()->beginTransaction();
try {
$this->_beforeSave();
if ($this->_dataSaveAllowed) {
$this->_getResource()->save($this);
$this->_afterSave();
}
$this->_getResource()->commit();
}
catch (Exception $e){
$this->_getResource()->rollBack();
throw $e;
}
return $this;
}
[/php]


此方法是一个典型 的模板方法,但是我们关注行3开启事务、行7保存数据、行10一切正常提交事务、行13发生异常回滚事务。这是一个典型的数据库操作。$this->_getResource()我们在上面以分析过,他将得到资源model类,要得到资资model类,肯定涉及到他的初始化,我们这里初始化的是类:Mage_Cms_Model_Mysql4_Page,他的父爷类:Mage_Core_Model_Resource_Abstract构造方法会调用子类实现的_construct方法(这里也相当模板方法吧,呵呵)

Mage_Cms_Model_Mysql4_Page中的_construct方法:
代码块10:

[php]
protected function _construct()
{
$this->_init(‘cms/page’, ‘page_id’);
}
[/php]


这里又出现了一个_init方法,并且他有两个参数,第一个参数据与上面的分析的的那两个参数值还相同。我在这里先给出这几个参数值的作用,等下我们从代码角度再来分析出他们的作用:
cms/page 中/前面的cms用来得到数据库联接使用,这个值约定与上面分析的那两个参数据的/前的那一部份相同(这个约定在资源model中的getTable方法中将体现)。page用来得到这个资源model的主表,第二个参数page_id,是主表中的id字段名(请参考<<设计模式在Magento中的应用–ActiveRecord>>).
他将调用父类Mage_Core_Model_Mysql4_Abstract中的_init方法:
代码块11:

[php]
protected function _init($mainTable, $idFieldName)
{
$this->_setMainTable($mainTable, $idFieldName);
}
[/php]


代码块12:

[php]
protected function _setMainTable($mainTable, $idFieldName=null)
{
$mainTableArr = explode(‘/’, $mainTable);
if (!empty($mainTableArr[1])) {
if (empty($this->_resourceModel)) {
$this->_setResource($mainTableArr[0]);
}
$this->_setMainTable($mainTableArr[1], $idFieldName);
} else {
$this->_mainTable = $mainTable;
if (is_null($idFieldName)) {
$idFieldName = $mainTable.’_id’;
}
$this->_idFieldName = $idFieldName;
}
return $this;
}
[/php]


代码块12是一个递归方法.在8行,它重新调用了自己.第三行把cms/page他成两个参数据[0]=>’cms’,[1]=>’page’,行4一定执行,行5此时为空,行6一定执行.把cms值传给_本类的_setResource方法,等下我们分析.然后执行8,把page,page_id传给自己,此时行三得到的值是[0]=>’page’,此时执行9 else分支,行10把page付给本类的类成员变量_mainTable,供后继使用,行11,12,13当没有传id域名时以主表名加_id组成,这里我们传了page_id,行14把page_id给本类成员变量_idFieldName,供后继使用.

_setResource方法分析(注意此时传入的值是cms),在这里我把要执行的代码拿出来,以防止干扰我们的思路.
代码块13:

[php]
protected function _setResource($connections, $tables=null)
{
$this->_resources = Mage::getSingleton(‘core/resource’);
$this->_resourcePrefix = $connections;
$this->_resourceModel = $this->_resourcePrefix;
}
[/php]


这个方法主要给三个类成员变量付值.

_resources: Mage_Core_Model_Resource类的一个实例,构造方法无定义
_resourcePrefix:资源前缀为cms,用来去找数据库联接使用
_resourceModel:此值为cms,目前我暂时只看到在getTable方法中使用

资源model中的beginTransaction方法.解决怎样得到数据库联接(解决图一中第二个泳道资源model中的3,4)

在继承分析之前我们理解一下magento系统是允许读/写分离的,也就是说写操作是一个数据,读是一个数据库,在magneto以外,我们可以利用数据库的同步,把写的数据同步到读的数据库,从而加速数据读/写的性能。所以magento有两种数据库联接,一种是读的(read),一种是写的(write),默认情况下他们是用的一个数据。在我们写magento后台代码是,一定要记住,读数据时一定使用read数据库联接,写数据是一定使用(write).这样为以后做读/写分离做准备。同时magento支持每一个模块有自己的数据库配置。

Mage_Core_Model_Resource_Abstract中beginTransaction方法定义:
代码块14:

[php]
public function beginTransaction()
{
$this->_getWriteAdapter()->beginTransaction();
return $this;
}
[/php]


子类Mage_Core_Model_Mysql4_Abstract将实现_getWriteAdapter()方法:
代码块15:

[php]
protected function _getWriteAdapter()
{
return $this->_getConnection(‘write’);
return $this;
}
[/php]


我们重点分析_getConnection方法,用来得到write(写)数据库的数据联接包装器。
代码块16:

[php]
protected function _getConnection($connectionName)
{
if (isset($this->_connections[$connectionName])) {
return $this->_connections[$connectionName];
}
if (!empty($this->_resourcePrefix)) {
$this->_connections[$connectionName] = $this->_resources->getConnection($this->_resourcePrefix.’_’.$connectionName);
} else {
$this->_connections[$connectionName] = $this->_resources->getConnection($connectionName);
}
return $this->_connections[$connectionName];
}
[/php]


这里我们传过来的:$connectionName值为:write.行3,4,5用来到本类类变量_connections中去取’write’联接是否存在。如果存在,直接返回。
行6将执行,由于本类中$this->_resourcePrefix值为cms,所以行7将会执行.行7将调用$this->_resources对象(Mage_Core_Model_Resource)中的getConnection方法去取write联接,此时传过去的参数为:cms_write.

代码块17:Mage_Core_Model_Resource中的getConnection方法的定义:

[php]
public function getConnection($name)
{
if (isset($this->_connections[$name])) {
return $this->_connections[$name];
}
$connConfig = Mage::getConfig()->getResourceConnectionConfig($name);
if (!$connConfig || !$connConfig->is(‘active’, 1)) {
return false;
}
$origName = $connConfig->getParent()->getName();
if (isset($this->_connections[$origName])) {
$this->_connections[$name] = $this->_connections[$origName];
return $this->_connections[$origName];
}
$typeInstance = $this->getConnectionTypeInstance((string)$connConfig->type);
$conn = $typeInstance->getConnection($connConfig);
$this->_connections[$name] = $conn;
if ($origName!==$name) {
$this->_connections[$origName] = $conn;
}
return $conn;
}
[/php]


这里传过来的$name的值为:cms_write
行3,4,5在类Mage_Core_Model_Resource中的_connections类变量中找是否已存在,如果存在就返回。行6调用Mage_Core_Model_Config类中的getResourceConnectionConfig方法,此类在初始化时我们分析过,在他里面有一个类变理中_xml持有magento所有config信息,并且提供给外界读取这些_xml节点信息的方法。其中getResourceConnectionConfig就是一个:定义如下:

代码块18:

[php]
public function getResourceConnectionConfig($name)
{
$config = $this->getResourceConfig($name);
if ($config) {
$conn = $config->connection;
if (!empty($conn->use)) {
return $this->getResourceConnectionConfig((string)$conn->use);
} else {
return $conn;
}
}
return false;
}
public function getResourceConfig($name)
{
return $this->_xml->global->resources->{$name};
}
[/php]


这里传过来的$name的值为:cms_write
这个方法是一个递归方法,第7行为自身的调用。
第3行的定义是14-17行,那么这里找的节点是global->resources->cms_write,我们把cms模块etc下的global->resources定义列出来,如下:
代码块19:

[xml]
<resources>
<cms_write>
<connection>
<use>core_write</use>
</connection>
</cms_write>
<cms_read>
<connection>
<use>core_read</use>
</connection>
</cms_read>
</resources>
[/xml]


代码块18行3得到cms_write节点,将执行到行7,此时的$conn->use值为:core_write.将会查找:global->resources->core_write,大家可以在app/etc/config.xml里找到此节点,此时的$conn->use值为:default_write.将会查找:global->resources->default_write,此时的$conn->use值为:default_setup,将会查找global->resources->default_setup节点,此节点没有use节点了,那么此时会返回global->resources->default_setup->connection节点。在这里您可以做一个练习,就是怎样把读写分开,怎样使一个模块使用不同的数据库.

程序执行将返回代码块17的第7行.
代码块17第10行,把default_setup给$origName变量,行11-14,用来到_connections类变量中找default_setup是否已存在,如果存在就返回.行15,16用已取得到的数据配置参数来得到一个Varien_Db_Adapter_Pdo_Mysql类的实例返回,里面的代码您可以跟踪进去看一下,这个类才是事务处理,sql处理真正的类.行,17,18,19把Varien_Db_Adapter_Pdo_Mysql产生的实例放到_connections['cms_write']和_connections['default_setup']中,供后继使用.

怎样取得代码块1中的真正的表名

我们在资源model中传入的_init中的第一个参数为’cms/page’,我们分析说page是主表,从代码1中可以看出,此时page只是entities下的一个节点名。如果要在资源model中得到真正的表名,需要使用:getMainTable()方法,如果在资源model中要得到不是主表,而是其它一些要用到的表,可以使用如:getTable(‘page_store’),我们这里不分析这两个方法的实现,大家可以去看一下他的实现。
在我们写代码中,一般一个表有一个值model,一个资源model,但不一定有资源Collection.这是这个表就是他的主表,如果在一些查询中要用到其它表,最好也配置在entities下,不要在sql中直接使用他的表名,而应该使用getTable方法。

如果要在此资源model之外,使用这个资源model中的表名,如有一个表的配置在这个资源mode下配置过了,其它地方要使用,则可以使用Mage::getSingleton(‘core/resource’)->getTableName(‘cms/page_store’);得到表名.

资源model中的CRUD操作
值model中的CRUD操作最终其实是通过资源model中的CRUD操作实现的,资源model中的CRUD操作都是模板方法,您可以去查看一下这4个方法。这4个方法会利用我们的数据库联接实例(Varien_Db_Adapter_Pdo_Mysql),生成sql,并利用这个实例执行这个sql.
这里说明一下新增/修改是的一种情况,有时您表中的值除了主key不能重复之外,还有一些列的值也不能重复,您可以在您的资源model的_construct()方法中加如下代码:$this->addUniqueField(array(‘field’ => ‘customer_id’,'title’ => ‘customerId’));,表名列customer_id值不能重复.

资源model可以执行任一sql

资源model有数据库联接实例(Varien_Db_Adapter_Pdo_Mysql),自然他可以执行您书写的任一sql.

三、资源Collection model

在对单条数据(不一定只是来自一张表中)进行操作时,我们经常使用值model就可以解决了,此时我们不会显示地调用资源model中的方法。而是直接调用model中的方法(此时的方法不一定是值model自带的CRUD方法,有时是我们自已定义的查询方法,此查询方法调用资源model中自定义查询方法得到数据返回给值model,值model拿到数据后,会填充到自身的_data变量中)。但对返回多条数据记录的操作时,我们有两种方式来处理:
1、避开使用值model,而是直接调用资源model对象中的自定义查询方法,如:$datas = Mage::getResourceSingleton(‘cms/page’)->自定义返回多条记录的方法.当然您也可以使用 Mage::getModel(‘cms/page’)->getResource()->自定义返回多条记录的方法,这种方式没有前一种方式好,因为他会多产生一个值model对象,当然如果此值model对象,在上文中已有了,则这样使用是可以的。
2、使用资源Collection model.得到一个资源Collection model也有两种方式,一是直接使用如:$datas = Mage::getResourceModel(‘cms/page_collection’),另外一种是$datas = Mage::getModel(‘cms/page’)->getCollection(),这两种方式都是可以的。资源Collection model的主要作为是用来处到多条数据记录,特别是分页。注意资源Collection model对象都继承自IteratorAggregate, Countable,所以拿到$datas,就可以直接循环了.

资源Collection model的初始化

我们这一部份主要分析资源Collection model.现在我们来看一下它的初始化.在这个实例中,我们的资源Collection model为:Mage_Cms_Model_Mysql4_Page_Collection.

Mage_Core_Model_Mysql4_Collection_Abstract中的构造方法
代码块20:

[php]
public function __construct($resource=null)
{
parent::__construct();
$this->_construct();
$this->_resource = $resource;
$this->setConnection($this->getResource()->getReadConnection());
$this->_initSelect();
}
[/php]


行3调用父类Varien_Data_Collection_Db的构造方法,您可以跟踪进去看一下,其实他啥都没有做。行4将调用Mage_Cms_Model_Mysql4_Page_Collection类的_construct()方法,行5把资源model对象放到类变量_resource,这个值给不给都是一样的,因为他的getResource方法,如果发现没有,他将去创立这个对象,行6从资源model中得到read联接对象,放入自己类变量_conn中,同时他会利用read联接对象创立select(Varien_Db_Select)对象,行7将初始化一下select对象,说是查询主表.我们一般利用资源Collection model时,不会自己去写sql,我们都是围绕select对象进行设置要查那些列,有一些什么样的where条件,是否要关联其它表等,select会自动帮我们把我们的设置转化成sql.

下面我们重点分析行3_construct()方法.Mage_Cms_Model_Mysql4_Page_Collection中的_construct()方法
代码块21:

[php]
protected function _construct()
{
$this->_init(‘cms/page’);
}
[/php]


行3说明将调用父类Mage_Core_Model_Mysql4_Collection_Abstract的_init方法,定义如下:
代码块22:

[php]
protected function _init($model, $resourceModel=null)
{
$this->setModel($model);
if (is_null($resourceModel)) {
$resourceModel = $model;
}
$this->setResourceModel($resourceModel);
return $this;
}
[/php]


从_init方法定义可以看出,其实他是的两个参数,第一个是值model的指示名,也就是外界怎样来找到这个值model的名称,如:$model = Mage::getModel(‘cms/page’);中的’cms/page’,第二个参数为资源model的指示名,也就是外界怎样找到这个资源model,它与值model中的_init方法中的参数的值和意义是一样的。行3把值model放入类变量_mode中(我们的资源Collection model会返回很多行数据,每一行的数据由这个值model持有)。4,5,6如果资源model指示名没有传,使用与值model相同的名称,第7行把资源model指示名给类变量$_resourceModel,供后继使用。

利用资源model的load方法得到数据

Varien_Data_Collection_Db中的load是一个模板方法,在数据加载后您可以在自己定义的资源Collection molde实现_afterLoad方法,对加载完成的数据进行一些后置处理工作。
资源Collection model实现IteratorAggregate, Countable,是一种迭代器模式在应用,可以用来做直接循环,在循环自动调用的方法中,将调用load方法,如方法getIterator中就调用了load.
默认情况下,load方法将加载主表中的所有列和所有行数据,如果您不需要主表中的所有列都查询出来,您可以在Mage_Cms_Model_Mysql4_Page_Collection重写他的_initSelect方法.如:
代码块23:

[php]
protected function _initSelect()
{
$this->getSelect()->from(array(‘main_table’ => $this->getResource()->getMainTable()),array(‘page_id’,'root_template’,'identifier’));
return $this;
}
[/php]


这样将只返回三列数.
如果您只需要root_template为one_column的行,那您可以这样写:
代码块24:

[php]
$collection = Mage::getModel(‘cms/page’)->getCollection()
$collection->addFilter(‘root_template’,'one_column’)
collection->load()
[/php]


如果您要关联cms_page_store进行查询,得到store_id,您可以这样写
代码块25:

[php]
$collection = Mage::getModel(‘cms/page’)->getCollection()
$collection->join(array(‘store_table’ => $this->getTable(‘cms/page_store’)),’main_table.page_id = store_table.page_id’,array(‘store_id’))
collection->load()
[/php]


如果您有很复杂很复杂的sql,又不要分页要写,建议您在资源model中直接写sql,然后在外调用。

在资源Collection model中主要方法,主要是围绕select这个对象进行的,建议您多看看这里面的源程序.

总结:
请回答以下问题:
1、magento 非eav model体系把model分成那三部份?他们之间的关系?
2、从外界怎样得到一个值model?他所传的参数所代表的意义?
3、值model中_init方法中的参数所代表的意义?
4、资源model中的_init方法中的参数所代表的意义?
5、资源model是怎样得到一个数据库联接的?
5、资源Collection model中的_init方法中的参数所代表的意义?
6、值model和资源model中的增删修查方法的应用那个设计模式?
7、资源Collection model中的sql是怎样生成的?

转载于:https://my.oschina.net/liufeng815/blog/353480

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`HttpPostActionInterface`是Magento 2框架中的一个接口,用于处理HTTP POST请求。它定义了一个方法`execute()`,该方法接收一个`RequestInterface`对象作为参数,并返回一个`ResultInterface`对象。 具体来说,当一个HTTP POST请求被发送到Magento应用程序时,Magento会根据请求中的路由信息调用相应的控制器类。控制器类将实现`HttpPostActionInterface`接口,并在`execute()`方法中执行请求处理逻辑。在`execute()`方法中,开发人员可以根据请求参数执行相应的操作,并返回一个表示操作结果的`ResultInterface`对象。 例如,以下代码片段演示了如何实现一个自定义的`HttpPostActionInterface`控制器类: ```php use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\App\RequestInterface; use Magento\Framework\Controller\ResultFactory; class MyController implements HttpPostActionInterface { public function execute(RequestInterface $request) { // 获取请求参数 $param1 = $request->getParam('param1'); $param2 = $request->getParam('param2'); // 执行相应的操作 // ... // 返回操作结果 $result = $this->resultFactory->create(ResultFactory::TYPE_JSON); $result->setData(['success' => true, 'message' => '操作成功']); return $result; } } ``` 在上述示例中,我们通过`$request->getParam()`方法获取了请求中的参数,并执行了相应的操作。最后,我们创建了一个JSON格式的`ResultInterface`对象并返回它,表示操作成功。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值