W tej chwili ponownie używam wielu kolekcji zagnieżdżonych w pętlach foreach. Czy można przenieść te rzeczy o kilka poziomów wyżej? Obecnie jestem zmuszony ponownie ładować kolekcje, które mają ponad 51 tys. Podmiotów, co znacznie spowalnia. W szczególności kolekcje kitinventory.
<?php
class Codespace_Module_Helper_Item extends other_one{
function functionOne($collection){
...
$data = $collection->getData();
foreach($data as $item){
$this->_functionTwo($item);
}
...
}
function _functionTwo($item){
$model = Mage::getModel('catalog/product');
$id = $model->getIdBySku($item['sku']);
$inventoryStatus = Mage::getResourceSingleton('catalog/product')->getAttributeRawValue($id, 'product_inventory_status', 1);
$invStatus = $model->getResource()->getAttribute('product_inventory_status')->getSource()->getOptionText($inventoryStatus);
if ($invStatus && $id) {
if ($invStatus !== 'Z') {
$stockItem = Mage::getModel('cataloginventory/stock_item');
$stockItem->setData(array());
$stockItem->loadByProduct($id);
if ($stockItem->getQty() != $item['quantity']) {
$stockItem->setQty(item['quantity']);
$stockItem->save();
$this->functionThree($item['sku']);
}
}
}
}
function functionThree($sku){
$collectionOfKits = Mage::getModel('kitinventory/kitinventory')->getCollection()->addFieldToFilter('related_sku',$sku);
if($collectionOfKits->getSize()){
foreach($collectionOfKits as $kit){
$kitSku = $kit->getSku();
$kitCollection = Mage::getModel('kitinventory/kitinventory')->getCollection()->addFieldToFilter('kit_sku',$kitSku)->setOrder('related_sku','ASC');
...
foreach($kitCollection as $component){
$componentSkus[] = $component->getRelatedSku();
$componentRequiredQuantity[] = $component->getRequiredQuantity();
}
$componentProductCollection = Mage::getModel('catalog/product')->getCollection();
$componentProductCollection->joinField('qty',
'cataloginventory/stock_item',
'qty',
'product_id=entity_id',
'{{table}}.stock_id=1',
'left');
$componentProductCollection->addAttributeToFilter('sku', array('in' => $componentSkus));
foreach($componentProductCollection as $component){
$quantity = $component->getQty();
...
}
$kitId= Mage::getModel('catalog/product')->getIdBySku($kitSku)
$kitStockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($kitId);
$this->functionFour($kitStockItem,$kitSku,$amountOfKitsPossible);
}
}
}
function functionFour($kitStockItem,$kitSku,$amountOfKitsPossible){
...
$kitStockItem->setQty($quantity);
$kitStockItem->save();
...
}
EDYCJA: to jest obecna funkcjonalność, którą wymyśliłem, wciąż uważam, że istnieje lepszy sposób na obsługę tych kolekcji.
collection
model
object
easymoden00b
źródło
źródło
functionOne($collection)
? W jakiej kolejności byłby rozmiar / liczba elementów? Czy konieczne jest zapętlenie go, aby uzyskać jednostki SKU?Odpowiedzi:
Jest kilka rzeczy, nad którymi możesz popracować;
&
deklarację parametru funkcji, npfunction hello(array &$world)
if
stwierdzenia, aby uzyskać mniej wcięć->cleanModelCache()->clearInstance()
zMage_Core_Model_Model_Abstract
wyczyścić dane źródłowe dla niektórych obiektów, może przyspieszyć rzeczy.Dodano zaktualizowaną wersję twojego kodu z kilkoma wbudowanymi zaleceniami na temat twojego obecnego kodu, mógłbym przejść trochę dalej, ale obecnie nie dodałby więcej.
Funkcja 1: Celem jest chodzenie po kolekcji
Funkcja 2: Celem jest aktualizacja zapasów, jeśli zostaną zmienione
Funkcja 3: Cel aktualizacji powiązanych pozycji magazynowych
Funkcja 4: Musiałem zgadywać (lub pecha), na razie jest to funkcja bezużyteczna, można ją dodać, tak jak w Funkcji 3.
źródło
Chciałem dodać to jako komentarz, ale nie mam jeszcze wystarczającej liczby przedstawicieli. Zobacz, jak siatki podstawowe Magento łączą ilość produktów z katalogiem / kolekcją produktów tutaj: https://github.com/OpenMage/magento-mirror/blob/magento-1.9/app/code/core/Mage/Adminhtml /Block/Catalog/Product/Grid.php#L65
Jeśli dołączysz do tabeli, aby uzyskać ilość, nie musisz wywoływać tego w pętli:
Mage::getModel('cataloginventory/stock_item')->loadByProduct($product)->getQty();
Inną alternatywą jest sprawdzenie, czy można buforować wyniki tego intensywnego systemu. Być może mógłbyś stworzyć drugą tabelę bazy danych do przechowywania wyników i sprawić, by odświeżyła się tak jak indeks magento.
źródło
Nie musisz ciągle ładować modelu,
Mage::getModel()
wystarczy odniesienie, nie wiedząc, w jaki sposób skonfigurowane są modele zasobów, trudno powiedzieć, czy jest on ponownie inicjowany za każdym razem w pamięci i w tych pętlach kończy się wyciek / wyczerpanie pamięć powodująca możliwość wymiany dysku.Jedna kolekcja, by rządzić nimi wszystkimi. Refaktoryzacja funkcji tak, aby odwoływała się tylko do jednej kolekcji. To samo dotyczy standardowego programowania SQL i proceduralnych. Poświęć nieco więcej czasu na sprawdzenie swoich kolekcji i modeli zasobów, w jaki sposób możesz uzyskać wszystkie potrzebne dane z SQL raz, może dwa razy, a następnie mieć wystarczającą ilość pamięci, a także odwoływać się do danych do zapętlenia w celu wyświetlenia / manipulacji. Łatwiej jest również zapisać jeden wynik w pamięci podręcznej niż wiele, to samo dotyczy wbudowanych mechanizmów buforowania MySQL, ponieważ częste żądania, które są wystarczająco duże, spowodują ten sam problem z wymianą dysku.
Zapisz I / O
Vinai ma dobry przykład wdrożenia tego samego podejścia:
Referencje :
źródło