Php Magento getSingleton()与getModel()问题
我想在Magento中循环一组产品ID。在循环中,我将产品的一些自定义属性显示为:Php Magento getSingleton()与getModel()问题,php,magento,singleton,Php,Magento,Singleton,我想在Magento中循环一组产品ID。在循环中,我将产品的一些自定义属性显示为: foreach ($products as $product) { $model = Mage::getSingleton('catalog/product')->load($product['id']); echo '<br>' . $model->getCredits(); } foreach($products作为$product){ $model=Mage::getS
foreach ($products as $product) {
$model = Mage::getSingleton('catalog/product')->load($product['id']);
echo '<br>' . $model->getCredits();
}
foreach($products作为$product){
$model=Mage::getSingleton('catalog/product')->load($product['id']);
回显“
”。$model->getCredits();
}
问题是,如果第一项的getCredits()
的值为true
,则所有后续项都显示true
,即使它们没有值true
但是当我使用Mage::getModel()
而不是Mage::getSingleton()
时,属性值显示正确
有人能解释一下这个区别吗?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);
}
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);
}
在您的情况下,您总是需要一个全新的产品对象/模型,因为每个产品都是唯一的…当您在整个应用程序中只需要一个对象实例时,您可以使用Singleton。因此,当您使用getSingleton时,它总是返回可以较早加载某些数据的相同对象 因此,在本例中,当循环启动时,它将创建新对象(当然,只有在magento中的其他位置没有这样做的情况下),并加载$product['id']的数据。在下一个循环迭代中,它使用以前的产品id数据获取相同的对象,并向其加载新的$product['id']数据。这就是为什么会出现一些问题
如果您想拥有两种不同的产品,必须使用getModel。
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
这就是你的情况。通过第二次使用getSingleton
,可以获得与第一次相同的产品实例。调用load
时,不会覆盖credits
的值,因为新加载的产品上没有此类值。结论:不要使用
getSingleton
。使用getModel
。或者如果要使用getSingleton
请在调用load
之前使用$model->setData(array())
。这将重置所有属性。您将在其他答案中找到getModel()和getSingleton()之间的差异
但是,如果要加快代码速度,假设您有一个集合,请执行以下操作:
$products->addAttributeToSelect('credits');
foreach ($products as $product) {
echo '<br>' . $product->getCredits();
}
$products->addAttributeToSelect('credits');
foreach($products as$product){
回显“
”。$product->getCredits();
}
因此,您不必加载每个产品,这非常耗时。首先,我想解释一下Mage::getSingleton()和Mage::getModel()函数之间的区别。 调用函数
Mage::getSingleton('catalog/product')
magento将在内存中搜索是否有可用的对象。如果没有,它将为Mage\u catalog\u Model\u product
类创建一个新对象。在foreach循环的第一次迭代中会发生这种情况。但从第二次迭代开始,当magento在内存中搜索Mage_catalog_Model_product class对象时,它将找到在第一次迭代中调用的对象。因此,magento不会创建任何新对象,而是调用内存中已存在的相同对象
但是,
如果使用
Mage::getModel('catalog/product)
此函数,无论何时调用它,都会在内存中创建Mage\u catalog\u Model\u product
类的新对象。因此,在循环中,该函数将在每次迭代中创建一个对象 Mage::getSingleton获取已存在的对象。Mage::getModel是新的一个对象。@MagikVishal:单例将不仅返回已经存在的对象。它将首先检查对象是否存在,如果不存在,它将创建一个在所有后续调用中使用的对象。->load(ID)
是否使singleton
加载新产品ID。我想我们只在注册表中存储模型对象。通过load()
的产品Id关联是如何工作的?加载时,它会填充新产品的数据。正如马吕斯在下面指出的那样:如果您有一些当前产品的数据集,而您将加载的产品中不存在这些数据,那么这些数据将不会被覆盖并保持不变……为什么->load($product['id'))
不足以通过singleton加载新模型?load将覆盖数据。因此,如果第一个产品中有一个“sku”,它将被覆盖。如果某些东西只存在于第一个产品中,而不存在于第二个产品中,那么第二个产品可能具有第一个产品的值。我想接受您的答案,但@KennyDs是第一个回答的。我猜您的意思是“不必加载每个属性”,对吗?您理解问题的正确性,但是$products
不是一个产品集合。但是它是一个Quotecollection.com,所以您可以使用:$product=Mage::getModel('catalog/product')->load($id,'credits');这不会加载所有属性。