Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Magento getSingleton()与getModel()问题_Php_Magento_Singleton - Fatal编程技术网

Php Magento getSingleton()与getModel()问题

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

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

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');这不会加载所有属性。