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
You can update memory limit for your script by setting unlimited memory are as follows.
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
this way you can get rid of
and just use $product model object from collection
secondly you will boost the whole thing by replacing
with
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