php Magento getSingleton() 与 getModel() 问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18756753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 18:10:00  来源:igfitidea点击:

Magento getSingleton() vs getModel() issue

phpmagentosingleton

提问by Arvind Bhardwaj

I want to loop over an array of product IDs in Magento. In the loop I am displaying some custom attributes of the products as:

我想在 Magento 中遍历一系列产品 ID。在循环中,我将产品的一些自定义属性显示为:

foreach ($products as $product) {
   $model = Mage::getSingleton('catalog/product')->load($product['id']);
   echo '<br>' . $model->getCredits();
}

Problem is that if the value of getCredits()for the first item is truethen all the subsequent items show trueeven if they do not have the value true.

问题是,如果getCredits()第一个项目的值为 ,true则所有后续项目都会显示,true即使它们没有该值true

But when I use Mage::getModel()instead of Mage::getSingleton(), the attribute values are displayed correct.

但是当我使用Mage::getModel()而不是时Mage::getSingleton(),属性值显示正确。

Can anyone please explain this difference?

任何人都可以解释这种差异吗?

回答by Kenny

Mage::getModel() will always return a new Object for the given model:

Mage::getModel() 将始终为给定模型返回一个新对象:

/**
 * Retrieve model object
 *
 * @link    Mage_Core_Model_Config::getModelInstance
 * @param   string $modelClass
 * @param   array|object $arguments
 * @return  Mage_Core_Model_Abstract|false
 */
public static function getModel($modelClass = '', $arguments = array())
{
    return self::getConfig()->getModelInstance($modelClass, $arguments);
}

Mage::getSingleton() will check whether the Object of the given model already exists and return that if it does. If it doesn't exist, it will create a new object of the given model and put in registry that it already exists. Next call will not return a new object but the existing one:

Mage::getSingleton() 将检查给定模型的对象是否已经存在,如果存在则返回。如果它不存在,它将创建给定模型的一个新对象,并将其放入已存在的注册表中。下一次调用不会返回新对象,而是返回现有对象:

/**
 * Retrieve model object singleton
 *
 * @param   string $modelClass
 * @param   array $arguments
 * @return  Mage_Core_Model_Abstract
 */
public static function getSingleton($modelClass='', array $arguments=array())
{
    $registryKey = '_singleton/'.$modelClass;
    if (!self::registry($registryKey)) {
        self::register($registryKey, self::getModel($modelClass, $arguments));
    }
    return self::registry($registryKey);
}

In your case you always want a completely new Product object/model since every product is unique...

在您的情况下,您总是想要一个全新的 Product 对象/模型,因为每个产品都是独一无二的......

回答by Marius

getModelwill return a new instance of the requested model every time.
getSingletonwill always return the same instance. It's the implementation of the Singleton design pattern for Magento.
There is also an other aspect that you have to keep in mind. The loadmethod does not remove all the data you have set on the product instance. For example if you do this:

getModel每次都会返回请求模型的新实例。
getSingleton将始终返回相同的实例。它是 Magento 单例设计模式的实现。
您还必须牢记另一个方面。该load方法不会删除您在产品实例上设置的所有数据。例如,如果您这样做:

$model = Mage::getModel('catalog/product')->setData('some_field_that_does_not_exist', 1);
$model->load(3);
echo $model->getData('some_field_that_does_not_exist'); //this prints 1

This is the case for you. By using getSingletonthe second time, you get the same product instance as the first time. And when calling loadthe value for creditsis not overwritten because there is no such value on the newly loaded product.
Conclusion: Do not use getSingleton. Use getModel. Or if you want to use getSingletonuse $model->setData(array())before calling load. This will reset all the attributes.

这就是你的情况。通过getSingleton第二次使用,您将获得与第一次相同的产品实例。并且在调用load值时credits不会被覆盖,因为新加载的产品上没有这样的值。
结论:不要使用getSingleton。使用getModel. 或者,如果您想在调用之前使用getSingletonuse 。这将重置所有属性。$model->setData(array())load

回答by Sukeshini

First of all I would like to explain the difference between Mage::getSingleton() and Mage::getModel() functions.

首先我想解释一下 difference between Mage::getSingleton() and Mage::getModel() functions.

When you call the function Mage::getSingleton('catalog/product')magento will search in the memory whether there is any object available. If not it will create a new object for Mage_catalog_Model_productclass. In the first iteration of the foreach loop this happens. But from the second iteration when magento searches in memory for Mage_catalog_Model_product class object it will find the object which was called in the first iteration. So magento won't create any new object and instead it will call the same object which is already in the memory.

当您调用该函数时,Mage::getSingleton('catalog/product')magento 将在内存中搜索是否有任何可用的对象。如果不是,它将为Mage_catalog_Model_product类创建一个新对象。在 foreach 循环的第一次迭代中会发生这种情况。但是从第二次迭代开始,当 magento 在内存中搜索 Mage_catalog_Model_product 类对象时,它将找到在第一次迭代中调用的对象。所以 magento 不会创建任何新对象,而是会调用内存中已经存在的相同对象。

BUT,

但,

If you use Mage::getModel('catalog/product)this function always creates new object of Mage_catalog_Model_productclass in the memory whenever you called it. So in the loop this function will create one object per iteration.

如果您使用Mage::getModel('catalog/product)此函数Mage_catalog_Model_product,则无论何时调用它,都始终在内存中创建新的类对象。因此,在循环中,此函数将在每次迭代中创建一个对象。

回答by Jakub Korupczyński

you use Singleton when you want only one instance of an object in whole application. So when you use getSingleton it always returns the same object that can have some data loaded earlier.

当您在整个应用程序中只需要一个对象实例时,您可以使用 Singleton。因此,当您使用 getSingleton 时,它始终返回可以早先加载某些数据的相同对象。

So in this case when the loop starts it create new object (of course only if this was not done before in some other place in magento) and loads the data for $product['id']. In next loop iteration it takes the same object with previous product id data and loads to it new $product['id'] data. This is why there can be some problems.

所以在这种情况下,当循环开始时,它会创建新对象(当然,前提是之前在 magento 的其他地方没有这样做)并加载 $product['id'] 的数据。在下一次循环迭代中,它采用与先前产品 id 数据相同的对象,并加载新的 $product['id'] 数据。这就是为什么会出现一些问题的原因。

If you want to have two different products you must use getModel.

如果您想拥有两种不同的产品,则必须使用 getModel。

回答by Ralf Siepker

You′ll find the difference between getModel() and getSingleton() in the other answers.

您会在其他答案中找到 getModel() 和 getSingleton() 之间的区别。

But if you want to speed up your code, assuming you have a collection, do the following:

但是如果你想加速你的代码,假设你有一个集合,请执行以下操作:

$products->addAttributeToSelect('credits');

foreach ($products as $product) {
   echo '<br>' . $product->getCredits();
}

So you don′t have to load every product, which is very time-consuming.

所以你不必加载每个产品,这是非常耗时的。