E 'possibile iterare su collezioni Magento con impaginazione in modo nativo?
-
16-10-2019 - |
Domanda
Quello che voglio dire con questo è - c'è un modo per farlo:
$collection = $model->getCollection();
foreach ($collection as $item) {
$item->doStuff();
}
In tal modo un che anche se la raccolta ha avuto 100k righe, sarebbe solo caricare una pagina di righe alla volta da MySQL e magicamente li impaginare per voi dietro le quinte.
Da guardando Varien_Data_Collection_Db::load()
non sembra come se fosse possibile, ma solo voluto controllare. Questo mi sembra qualcosa che dovrebbe essere un bisogno comune.
Soluzione
Si dovrebbe usare
Mage::getSingleton('core/resource_iterator')
A tal fine, come esiste esclusivamente per i motivi di prestazioni che hai citato.
In caso contrario, è possibile utilizzare una soluzione un po 'meno elegante utilizzando un ciclo con setPageSize
- c'è un buon esempio, https://stackoverflow.com/questions/3786826/how-to-loop-a-magento-collection
Altri suggerimenti
Sono d'accordo con Ben Lessani che si dovrebbe utilizzare il modello di risorse core/iterator
per caricare grandi collezioni di una riga alla tempo di se possibile .
Tuttavia, ci sono delle limitazioni. Come spiegato in " addAttributeToSelect non funziona con anima / resource_iterator? " non funziona bene con i modelli EAV se avete bisogno per includere valori dalle tabelle dei valori degli attributi.
E l'esempio collegato da StackOverflow non è in realtà che un bene perché si ripete la stessa query con espressioni diverse LIMIT
. Per query complesse questo potrebbe essere un problema di prestazioni, ma ancora più importante, si otterrà i duplicati se vengono aggiunte nuove righe in mezzo.
Un modo migliore per collezioni maniglia a blocchi è di primo carico tutti gli ID, quindi utilizzare queste ids come filtro per la collezione reale di paging.
Semplice esempio per i prodotti:
$ids = Mage::getModel('catalog/product')
->getCollection()
->getAllIds();
$page = 1;
do {
$collection = Mage::getModel('catalog/product')
->getCollection()
->addIdFilter($ids)
->setPageSize(100)
->setCurPage($page);
$results = $collection->load();
// do stuff ......
$page++;
} while ($results->count());