14

Magento で製品 ID の配列をループしたいと考えています。ループでは、製品のカスタム属性を次のように表示しています。

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

問題はgetCredits()、最初のアイテムの値が の場合、値がなくてもtrue後続のすべてのアイテムが表示されることです。truetrue

しかし、Mage::getModel()代わりにを使用するとMage::getSingleton()、属性値が正しく表示されます。

誰かこの違いを説明してくれませんか?

4

5 に答える 5

31

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() は、指定されたモデルのオブジェクトが既に存在するかどうかを確認し、存在する場合はそれを返します。存在しない場合は、指定されたモデルの新しいオブジェクトを作成し、既に存在するレジストリに入れます。次の呼び出しは、新しいオブジェクトではなく、既存のオブジェクトを返します。

/**
 * 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);
}

あなたの場合、すべての製品が一意であるため、常に完全に新しい製品オブジェクト/モデルが必要です...

于 2013-09-12T06:39:56.640 に答える
11

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

これはあなたの場合です。2 回目に使用getSingletonすると、1 回目と同じ製品インスタンスが得られます。また、新しくロードされた製品にはそのような値がないためload、値を呼び出すと上書きされません。結論: 使用しないでください。を使用します。または、呼び出す前に使用したい場合。これにより、すべての属性がリセットされます。credits
getSingletongetModelgetSingleton$model->setData(array())load

于 2013-09-12T06:43:31.300 に答える
5

まず最初に説明したいのは、difference between Mage::getSingleton() and Mage::getModel() functions.

関数Mage::getSingleton('catalog/product')magento を呼び出すと、使用可能なオブジェクトがあるかどうかがメモリ内で検索されます。Mage_catalog_Model_productそうでない場合は、クラスの新しいオブジェクトを作成します。foreach ループの最初の繰り返しで、これが発生します。しかし、magento がメモリ内で Mage_catalog_Model_product クラス オブジェクトを検索する 2 回目の反復から、最初の反復で呼び出されたオブジェクトが見つかります。そのため、magento は新しいオブジェクトを作成せず、代わりに既にメモリ内にある同じオブジェクトを呼び出します。

しかし、

この関数を使用すると、呼び出すたびにメモリ内Mage::getModel('catalog/product)にクラスの新しいオブジェクトが常に作成されます。Mage_catalog_Model_productしたがって、ループ内で、この関数は反復ごとに 1 つのオブジェクトを作成します。

于 2013-09-12T08:56:34.033 に答える
2

他の回答で getModel() と getSingleton() の違いを見つけることができます。

ただし、コレクションがあると仮定して、コードを高速化したい場合は、次のようにします。

$products->addAttributeToSelect('credits');

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

そのため、非常に時間がかかるすべての製品をロードする必要はありません。

于 2013-09-12T08:41:34.253 に答える