skip to Main Content

i have a script that updates or deletes products from magento, but i notice that consumes a lot of memory, i already get

PHP Fatal error:  Allowed memory size of 4294967296 bytes exhausted (tried to allocate 130968 bytes) in /home/public_html/lib/Zend/Locale/Data.php on line 852

So maybe the problem is with my script, maybe it must be optmized.

Steps that my script takes:

1- Make api call to get all products from our distribuitor

2- Get all Products from our store;

3- Loops are online store products collection;

4- On the iteration of each products searchs for the product inside the data from the api call, if exists the product it should update the stock and price, if doesnt exist it should delete the product since it doesnt exist.

Here is my code and maybe anybody can find what is wrong.

set_time_limit(0);
ini_set('memory_limit', '4096M');

require 'app/Mage.php';
umask(0);
Mage::app();
Mage::register('isSecureArea', 1);

$productCollection = Mage::getResourceModel('catalog/product_collection')
                       ->addFieldToFilter(array(
                        array('attribute'=>'reference','neq'=>''),
));

//Get all Products API
$data = curlRequestObject("rest/catalog/products.xml?isoCode=pt");   

$productCollectionLength = count($productCollection);

foreach ($productCollection as $product) {
try {
    $reference = $product->getReference();
    $res = $data->xpath("item/sku[.='{$reference}']/parent::*"); 

    //Product Info
    $productID = $res[0]->id;

    $price = $res[0]->retailPrice;

    if (count($res) <= 0){
       echo $product->getId() ." Deletec." . PHP_EOL;
       $product->delete();
       continue;
    }

    //Update Stock
    $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product->getId());
    $stockAvailable = checkStock($productID);
    if ($stockItem->getId() > 0 and $stockItem->getManageStock()) {
      $qty = $stockAvailable;
      $stockItem->setQty($qty);
      $stockItem->setIsInStock((int)($qty > 0));
      $stockItem->save();
    }

    //Update Price
    $priceUpdate = Mage::getModel('catalog/product')->load($product->getId());
    $priceUpdate->setPrice($price);

    if($priceUpdate->getSpecialPrice() > $price){
      $priceUpdate->setSpecialPrice("");
    }
    $priceUpdate->save();

     echo $product->getReference() . PHP_EOL;

     } catch (Exception $e) {
            echo $e->getMessage() . PHP_EOL;
        }
}

function curlRequestObject($api = "rest/catalog/category/2399.xml?isoCode=pt")
  {

    $ch = curl_init("http://api.domain.com/".$api);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: text/xml; charset=UTF-8',
         'Authorization: Bearer hashasdada',
        'Accept: text/plain'
      ));

      $data = curl_exec($ch);

      curl_close($ch);

      $oXML = new SimpleXMLElement( $data );

      return $oXML;



  }

  function checkStock($id = 0)
  {

   /* if($id === 0){
      return http_response_code(404);
    }*/
    $api = "rest/catalog/productstock/".$id.".xml?isoCode=pt";
    $ch = curl_init("http://api.domain.com/".$api);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: text/xml; charset=UTF-8',
         'Authorization: Bearer dasdsa',
        'Accept: text/plain'
      ));

      $data = curl_exec($ch);

      curl_close($ch);

      $oXML = new SimpleXMLElement( $data );

      return $oXML->stocks->quantity;



  }

2

Answers


  1. You can update memory limit for your script by setting unlimited memory are as follows.

    ini_set("memory_limit",-1); // Add this line in your starting part of the script.
    
    Login or Signup to reply.
  2. Methods like load and save on product model (‘catalog/product’) consume a lot of memory.(and fire some events)

    since you are iterating through a product collection (‘catalog/product_collection’) anyway, you may add your getter attributes to collection query by

    $productCollection = Mage::getResourceModel('catalog/product_collection')
                ->addAttributeToSelect('special_price')
                ->addAttributeToSelect('reference')
                ->addFieldToFilter(array(
                            array('attribute'=>'reference','neq'=>''),
    ));
    

    this way you can get rid of

    Mage::getModel('catalog/product')->load($product->getId());
    

    and just use $product model object from collection

    secondly you will boost the whole thing by replacing

    $priceUpdate->setPrice($price);
    $priceUpdate->save();
    

    with

    $product->setPrice($price);
    $product->getResource()->saveAttribute($product, 'price');
    

    and same with special_price

    Enable and run Product Flat Data, this will speed up collection performance if you have a lot of attributes and under 100k products

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search