En ce moment, je réutilise un grand nombre de collections imbriquées dans des boucles foreach. Est-il possible de déplacer ces choses à plusieurs niveaux? Actuellement, je suis obligé de recharger des collections qui ont 51k + entités encore et encore, ce qui ralentit considérablement les choses. Plus précisément les collections 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();
...
}
EDIT: c'est la fonctionnalité actuelle que j'ai proposée, je pense toujours qu'il existe une meilleure façon de gérer ces collections.
collection
model
object
easymoden00b
la source
la source
functionOne($collection)
? Dans quel ordre serait sa taille / nombre d'articles? Est-il nécessaire de boucler dessus pour obtenir les SKU?Réponses:
Il y a quelques choses sur lesquelles vous pouvez travailler;
&
dans la déclaration de paramètre de fonction commefunction hello(array &$world)
if
déclarations plus intelligentes pour obtenir moins d'indentation->cleanModelCache()->clearInstance()
partirMage_Core_Model_Model_Abstract
pour effacer les données sous - jacentes pour certains objets, peuvent accélérer les choses.Ajout d'une version mise à jour de votre code avec quelques recommandations en ligne sur votre code actuel, je pourrais continuer un peu, mais il n'y ajouterait actuellement rien de plus.
Fonction 1: Le but est de parcourir la collection
Fonction 2: le but est de mettre à jour le stock en cas de changement
Fonction 3: Objectif de la mise à jour des articles en stock associés
Fonction 4: J'ai dû faire des suppositions chanceuses (ou malchanceuses), pour l'instant c'est une fonction inutile, pourrait être ajoutée telle quelle dans la fonction 3.
la source
Je voulais ajouter ceci en tant que commentaire mais je n'ai pas encore assez de représentants. Jetez un œil à la façon dont les grilles de base Magento joignent la quantité de produits à la collection de produits / catalogue ici: https://github.com/OpenMage/magento-mirror/blob/magento-1.9/app/code/core/Mage/Adminhtml /Block/Catalog/Product/Grid.php#L65
Si vous rejoignez la table pour obtenir la quantité, vous n'avez pas besoin d'appeler cela en boucle:
Mage::getModel('cataloginventory/stock_item')->loadByProduct($product)->getQty();
L'autre alternative consiste à voir si vous pouvez mettre en cache les résultats de ce processus intensif du système. Peut-être pourriez-vous créer une deuxième table de base de données pour stocker les résultats et l'actualiser comme le ferait un index magento.
la source
Vous n'avez pas besoin de recharger le modèle encore et encore,
Mage::getModel()
avec une référence suffit sans savoir comment vos modèles de ressources sont configurés, il est difficile de dire s'il est réinitialisé à chaque fois en mémoire et dans ces boucles, vous finissez par fuir / manquer de mémoire entraînant éventuellement un échange de disque.Une collection pour les gouverner tous. Refactorisation des fonctions pour ne référencer que la seule collection. C'est la même chose avec la programmation SQL et procédurale standard. Prenez un peu plus de temps pour enquêter sur vos collections et modèles de ressources sur la façon dont vous pouvez obtenir toutes les données dont vous avez besoin à partir de SQL une fois, peut-être deux fois, puis avoir suffisamment de mémoire en place ainsi que référencer les données pour boucler pour l'affichage / la manipulation. Il est également plus facile de stocker un résultat dans le cache contre plusieurs, c'est également le cas pour les mécanismes de mise en cache intégrés de MySQL, car les demandes fréquentes qui sont suffisamment importantes entraîneront le même problème d'échange de disque.
Enregistrez les E / S
Vinai a un bon exemple de mise en œuvre de la même approche:
Les références :
la source