En este momento estoy reutilizando muchas colecciones que están anidadas dentro de los bucles foreach. ¿Es posible subir estas cosas algunos niveles? Actualmente me veo obligado a recargar colecciones que tienen más de 51k entidades una y otra vez, lo que ralentiza enormemente las cosas. Específicamente las colecciones 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();
...
}
EDITAR: esta es la funcionalidad actual que se me ocurrió, todavía creo que hay una mejor manera de manejar estas colecciones.
collection
model
object
easymoden00b
fuente
fuente
functionOne($collection)
? ¿En qué orden sería el tamaño / número de artículos? ¿Es necesario recorrerlo para obtener los SKU?Respuestas:
Hay algunas cosas en las que puedes trabajar;
&
en la declaración de parámetro de función comofunction hello(array &$world)
if
declaraciones más inteligentes para obtener menos sangría->cleanModelCache()->clearInstance()
desdeMage_Core_Model_Model_Abstract
para borrar los datos subyacentes de algunos objetos, puede acelerar las cosas.Agregué una versión actualizada de su código con algunas recomendaciones en línea sobre su código actual, podría continuar un poco, pero actualmente no agregaría más.
Función 1: el propósito es caminar por la colección
Función 2: el propósito es actualizar el stock si se modifica
Función 3: Propósito actualizar artículos de stock relacionados
Función 4: Tuve que hacer algunas conjeturas afortunadas (o desafortunadas), por ahora es una función inútil, podría agregarse como está en la Función 3.
fuente
Quería agregar esto como un comentario, pero aún no tengo suficiente representante. Eche un vistazo a cómo las cuadrículas principales de Magento unen la cantidad de productos al catálogo / colección de productos aquí: https://github.com/OpenMage/magento-mirror/blob/magento-1.9/app/code/core/Mage/Adminhtml /Block/Catalog/Product/Grid.php#L65
Si te unes a la tabla para obtener la cantidad, no tienes que llamar a esto en un bucle:
Mage::getModel('cataloginventory/stock_item')->loadByProduct($product)->getQty();
La otra alternativa es ver si puede almacenar en caché los resultados de este proceso intensivo del sistema. Tal vez podría hacer una segunda tabla de base de datos para almacenar los resultados y hacer que se actualice como lo haría un índice de magento.
fuente
No es necesario volver a cargar el modelo una y otra vez,
Mage::getModel()
con una referencia es suficiente sin saber cómo están configurados sus modelos de recursos, es difícil decir si se reinicia cada vez en la memoria y en esos bucles termina goteando / quedando sin memoria causando el intercambio de disco posiblemente.Una colección para gobernarlos a todos. Refactorizando las funciones para hacer referencia solo a una colección. Esto es lo mismo con SQL estándar y programación de procedimientos. Dedique un poco más de tiempo a investigar sus colecciones y modelos de recursos sobre cómo puede obtener todos los datos que necesita de SQL una vez, tal vez dos veces y luego tener suficiente memoria en su lugar, así como hacer referencia a los datos para realizar un bucle para su visualización / manipulación. También es más fácil almacenar un resultado en caché frente a muchos, este es el mismo caso para los mecanismos de almacenamiento en caché integrados de MySQL también, ya que las solicitudes frecuentes que son lo suficientemente grandes causarán el mismo problema de intercambio de disco.
Guarde la E / S
Vinai tiene un buen ejemplo de implementación del mismo enfoque:
referencias :
fuente