Сейчас я повторно использую множество коллекций, которые вложены в циклы foreach. Можно ли поднять эти вещи на несколько уровней? В настоящее время я вынужден многократно перезагружать коллекции, в которых есть 51 тыс. Объектов, что сильно замедляет работу. В частности, коллекции инвентаря.
<?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();
...
}
РЕДАКТИРОВАТЬ: это текущая функциональность, я придумал, я все еще думаю, что есть лучший способ обрабатывать эти коллекции.
collection
model
object
easymoden00b
источник
источник
functionOne($collection)
? В каком порядке это будет размер / количество предметов? Нужно ли зацикливаться на нем, чтобы получить SKU?Ответы:
Есть несколько вещей, над которыми вы можете работать;
&
в объявление параметра функции, какfunction hello(array &$world)
if
заявления, чтобы получить меньше отступов->cleanModelCache()->clearInstance()
с,Mage_Core_Model_Model_Abstract
чтобы очистить базовые данные для некоторых объектов, может ускорить процесс.Добавил обновленную версию вашего кода с некоторыми встроенными рекомендациями по вашему текущему коду, я мог бы продолжить, но в настоящее время он не добавил бы к нему больше.
Функция 1: цель ходит по коллекции
Функция 2: цель обновления запаса, если изменилось
Функция 3: Цель обновления связанных товарных позиций
Функция 4: Нужно было сделать некоторые удачные (или неудачные) догадки, потому что теперь это бесполезная функция, может быть добавлена, как в функции 3.
источник
Я хотел добавить это в качестве комментария, но у меня еще недостаточно представителей. Посмотрите, как основные сетки Magento объединяют количество продуктов с каталогом / коллекцией продуктов здесь: https://github.com/OpenMage/magento-mirror/blob/magento-1.9/app/code/core/Mage/Adminhtml /Block/Catalog/Product/Grid.php#L65
Если вы присоединяетесь к таблице, чтобы получить кол-во, вам не нужно вызывать это в цикле:
Mage::getModel('cataloginventory/stock_item')->loadByProduct($product)->getQty();
Другой вариант - посмотреть, сможете ли вы кешировать результаты этого интенсивного процесса. Возможно, вы могли бы создать вторую таблицу базы данных для хранения результатов и обновить ее, как это сделал бы индекс magento.
источник
Вам не нужно перезагружать модель снова и снова,
Mage::getModel()
достаточно справки, не зная, как настроены ваши модели ресурсов, трудно сказать, повторяется ли она каждый раз в памяти, и в этих циклах вы заканчиваете утечкой / исчерпанием Возможно, произошла перестановка памяти.Одна коллекция, чтобы править ими всеми. Рефакторинг функций для ссылки только на одну коллекцию. Это то же самое со стандартным SQL и процедурным программированием. Потратьте немного больше времени на изучение своих коллекций и моделей ресурсов на предмет того, как вы можете получить все необходимые данные из SQL один раз, возможно, дважды, а затем иметь достаточно памяти, а также ссылки на данные для циклического отображения для отображения / манипуляции. Кроме того, проще хранить один результат в кэше, чем во многих, это то же самое относится и к встроенным механизмам кэширования MySQL, поскольку частые запросы, которые достаточно велики, вызовут ту же проблему подкачки диска.
Сохранить ввод / вывод
Vinai имеет хороший пример реализации того же подхода:
Рекомендации :
источник