Проблема Magento getSingleton () против getModel ()

Я хочу перебрать массив идентификаторов продуктов в Magento. В цикле я показываю некоторые пользовательские атрибуты продуктов как:

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

Проблема в том, что если значение getCredits() для первого элемента равно true то все последующие элементы отображают true даже если они не имеют значения true .

Но когда я использую Mage::getModel() вместо Mage::getSingleton() , значения атрибутов отображаются корректно.

Может ли кто-нибудь объяснить эту разницу?

Related of "Проблема Magento getSingleton () против getModel ()"

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

В вашем случае вы всегда хотите совершенно новый объект / модель продукта, поскольку каждый продукт уникален …

getModel будет возвращать новый экземпляр запрашиваемой модели каждый раз.
getSingleton всегда будет возвращать один и тот же экземпляр. Это реализация шаблона проектирования Singleton для 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 используйте $model->setData(array()) перед вызовом load . Это приведет к сбросу всех атрибутов.

вы используете Singleton, если хотите только один экземпляр объекта в целом приложении. Поэтому, когда вы используете getSingleton, он всегда возвращает тот же объект, который может иметь некоторые ранее загруженные данные.

Поэтому в этом случае при запуске цикла создается новый объект (конечно, только если это не было сделано раньше в каком-либо другом месте в magento) и загружает данные для $ product ['id']. В следующей итерации цикла он принимает тот же объект с предыдущими данными идентификатора продукта и загружает в него новые данные $ product ['id']. Вот почему могут возникнуть некоторые проблемы.

Если вы хотите иметь два разных продукта, вы должны использовать getModel.

Прежде всего, я хотел бы объяснить 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 в памяти всякий раз, когда вы его вызывали. Таким образом, в цикле эта функция создаст один объект на итерацию.

Вы найдете разницу между getModel () и getSingleton () в других ответах.

Но если вы хотите ускорить свой код, если у вас есть коллекция, сделайте следующее:

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

Поэтому вам не нужно загружать каждый продукт, что очень трудоемко.