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
Magento getSingleton() vs getModel() issue
提问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 true
then all the subsequent items show true
even 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
getModel
will return a new instance of the requested model every time.getSingleton
will 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 load
method 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 getSingleton
the second time, you get the same product instance as the first time. And when calling load
the value for credits
is 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 getSingleton
use $model->setData(array())
before calling load
. This will reset all the attributes.
这就是你的情况。通过getSingleton
第二次使用,您将获得与第一次相同的产品实例。并且在调用load
值时credits
不会被覆盖,因为新加载的产品上没有这样的值。
结论:不要使用getSingleton
。使用getModel
. 或者,如果您想在调用之前使用getSingleton
use 。这将重置所有属性。$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_product
class. 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_product
class 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.
所以你不必加载每个产品,这是非常耗时的。