2011-09-14 38 views
2

我最近在調用大型產品集合時使用Magento的資源迭代器模型以節省資源 - http://www.fontis.com.au/blog/magento/loading-large-collections。然而,我發現很難弄清楚如何讓它輸出完全相同的數據。在產品集合上使用Magento的資源迭代器模型

因此,假設我使用下面的獲得完整的產品採集和輸出的SKU:

$productCollection = Mage::getModel('catalog/product')->getCollection(); 
foreach($productCollection as $product){ 
    echo $product->getSku().','; 
} 

使用Profiler,我看這是使用1154480個字節來處理。

現在使用資源模型迭代器,像這樣:

function productCallback($args) 
{ 
    $product = Mage::getModel('catalog/product'); 
     $product->setData($args['row']); 
     echo $product->getSku().','; 
} 
$_productCollection = Mage::getModel('catalog/product')->getCollection();; 
$_productCollection = Mage::getSingleton('core/resource_iterator')->walk($_productCollection->getSelect(), array('productCallback')); 

這使用199912個字節。因此,獲得同樣的東西非常重要,只是sku的基本列表。

但我的問題是,例如,如果我想使產品一個很好的樣式列表,並得到他們的圖片,網址等,我將以前使用foreach循環在$ productCollection,如在第一個例子:

foreach($_productCollection as $product){ 
echo $product->getSku().','; 
}; 

但是,這不再起作用。它看起來像通過回調時,它的行爲與foreach循環相同,依次運行每個產品。

那麼,如何讓我的集合恢復到與之前相同的格式,因此它再次在foreach循環中工作?我需要將產品添加到數組嗎?如果是這樣,我該怎麼做?

回答

2

我想你可能會錯過這一點。當您不需要完整的面向對象的方法,也不需要記錄數組,並且可以使用數據庫中的原始值時,資源迭代器就非常好。

對於輸出圖像和價格等東西,您需要具有製作圖像縮略圖功能的產品對象實例或折扣如何影響價格。當產品對象加載時,它會觸發各種事件,以便其他模塊也可以進行修改,這也是Magento如此可擴展的一部分。如果你擔心內存使用或執行時間,那麼cache the product list block並不會改變其他任何東西。

+0

的事情是,如果我想要的產品集合說最好 - 我不希望它緩存,因爲它不會實時更新。但是我說我只想要4種產品,即使我只是指定要返回4種產品的圖像,名稱,價格等,它仍然貫穿整個系列。所以,我想如果我只是使用資源迭代器來獲取4個必需的sku,那麼在foreach循環中,我可以使用sku來加載我需要的4個產品的數據。 –

+0

在暢銷書的情況下,我會說你仍然應該緩存輸出,但是有一個受訂單影響的緩存標籤。當訂單被放置(出售物品),然後刷新呈現的輸出。 – clockworkgeek

+0

如果您可以按照已售出的數量過濾產品收集,那麼您可以避免遍歷整個收集。首先在SQL中執行,以免在PHP中完成。您目前如何衡量銷售量? – clockworkgeek

1

@clockworkgeek - 你是對的。要添加到這一點,

$visibility = array(
         Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH, 
         Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG 
       ); 

$_productCollection = Mage::getResourceModel('reports/product_collection') 
           ->addAttributeToSelect('*') 
           ->addOrderedQty() 
           ->addAttributeToFilter('visibility', $visibility) 
           ->setOrder('ordered_qty', 'desc'); 
+0

也許你也可以使用'setPageSize(4)'來限制返回對象的數量。 – clockworkgeek

+0

另一個選項是' - > setPage(1,4)' –

0

此問題已做了前一段時間,但我想補充,可以裝載產品在回調函數得到任何屬性,你需要並將其存儲在一個對象的保護成員數組通過公共方法。

例如,你可以有一個像

class Company_Module_Model_Indexer_Entity_Product 
    public function addToData($key, $data) 
    { 
     $this->_data[$key] = $data; 
    } 

一個模型,然後這個類的一個方法中,你可以有:

Mage::getSingleton('core/resource_iterator')->walk($products->getSelect(), array(
      function ($args) { 
       $rowProduct = Mage::getModel('catalog/product')->setData($args['row']); 
       $indexKey = $rowProduct->getId(); 
       $product = Mage::getModel('catalog/product')->load($rowProduct->getId()); 

       $args['invoker']->addToData($indexKey, [YOUR_DATA]); 
      } 
     ), array('invoker' => $this));