我想在Magento中循环一系列产品ID。在循环中,我将产品的一些自定义属性显示为:
foreach ($products as $product) {
$model = Mage::getSingleton('catalog/product')->load($product['id']);
echo '<br>' . $model->getCredits();
}
问题是,如果第一项的getCredits()
值为true
,则所有后续项目都会显示true
,即使它们没有值true
。
但是当我使用Mage::getModel()
代替Mage::getSingleton()
时,属性值显示正确。
有人可以解释一下这个区别吗?
答案 0 :(得分:30)
Mage :: getModel()将始终返回给定模型的新Object:
/**
* 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()将检查给定模型的Object是否已经存在,如果存在则返回。如果它不存在,它将创建给定模型的新对象并将其存在于注册表中。下一次调用不会返回新对象,而是返回现有对象:
/**
* 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);
}
在您的情况下,您总是需要一个全新的产品对象/模型,因为每个产品都是独一无二的......
答案 1 :(得分:10)
getModel
每次都会返回所请求模型的新实例
getSingleton
将始终返回相同的实例。这是Magento的Singleton设计模式的实现
您还必须牢记其他方面。 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
就是这种情况。通过第二次使用getSingleton
,您将获得与第一次相同的产品实例。在调用load
时,credits
的值不会被覆盖,因为新加载的产品上没有此值。
结论:不要使用getSingleton
。使用getModel
。或者,如果您想在调用getSingleton
之前使用$model->setData(array())
使用load
。这将重置所有属性。
答案 2 :(得分:4)
如果在整个应用程序中只需要一个对象实例,则使用Singleton。因此,当您使用getSingleton时,它总是返回可以在之前加载一些数据的相同对象。
因此,在这种情况下,当循环开始时,它会创建新对象(当然,只有在以前没有在magento的其他位置进行过此操作)并加载$ product ['id']的数据。在下一个循环迭代中,它使用与先前产品id数据相同的对象,并向其加载新的$ product ['id']数据。这就是为什么会有一些问题。
如果您想拥有两种不同的产品,则必须使用getModel。
答案 3 :(得分:3)
首先,我想解释difference between Mage::getSingleton() and Mage::getModel() functions.
当您调用函数Mage::getSingleton('catalog/product')
时,magento将在内存中搜索是否有可用的对象。如果不是,它将为Mage_catalog_Model_product
类创建一个新对象。在foreach循环的第一次迭代中,会发生这种情况。但是从第二次迭代开始,当magento在内存中搜索Mage_catalog_Model_product类对象时,它将找到在第一次迭代中调用的对象。所以magento不会创建任何新对象,而是会调用已经在内存中的同一个对象。
,但
如果你使用Mage::getModel('catalog/product)
这个函数总是在你调用它时在内存中创建Mage_catalog_Model_product
类的新对象。因此在循环中,此函数将在每次迭代时创建一个对象。
答案 4 :(得分:2)
您可以在其他答案中找到getModel()和getSingleton()之间的区别。
但是如果你想加速你的代码,假设你有一个集合,请执行以下操作:
$products->addAttributeToSelect('credits');
foreach ($products as $product) {
echo '<br>' . $product->getCredits();
}
所以你不必加载每件产品,这非常耗时。