Sven B Sven B - 21 days ago 8
PHP Question

Laravel out of memory

Im trying to export my data to an excel sheet but I get the error:


FatalErrorException in Connection.php line 321: Allowed memory size of
134217728 bytes exhausted (tried to allocate 196605 bytes)


I understand I could just up the memory limit of php but I like to understand why my code takes up so much memory.

My code:

public function exportExcel()
{

$datum = date("d-m-Y");


Excel::create('Sales export '.$datum, function($excel) {


$datum = date("d-m-Y");

// Chain the setters
$excel->setCreator('some name')
->setCompany('some company')
->setDescription('sales export.')
->setTitle('Salesexport '.$datum);

$excel->sheet('sales '.$datum, function($sheet) {
$orders = Order::orderBy('created_at','desc')->get();
$sheet->appendRow(array(
"merk","product","artikel nr","categorie","collectie","maat","omschrijving","inkoopprijs","verkoopprijs","prijs betaald","aantal verkocht","verkocht aan", "totaal","dag","maand","jaar","kwartaal","reseller","verkoper","bestel naam"
));
foreach($orders as $order)
{

foreach($order->products as $p)
{

$sizeLink = $p->productSize;
$productLink = $sizeLink->product;


// Append row as very last
$sheet->appendRow(array(
$productLink->brand->name,
$productLink->name,
$productLink->artnr,
$productLink->category->name,
$productLink->collection->name,
$sizeLink->size->name,
$productLink->desciption,
number_format((float) $productLink->price_buy_in, 2, ',', ''),
number_format((float) $productLink->price, 2, ',', ''),
number_format((float) $p->price, 2, ',', ''),
$p->quantity, //geboekt aantal
$order->billingname . $order->billingnamelast,
number_format((float) $p->quantity * $p->price, 2, ',', ''), // totaal kosten
//number_format((float) ($p->quantity * $p->price - $p->quantity * $p->price_buy_in), 2, ',', ''), // winst inkoop-verkoop
date("d",strtotime($order->created_at)),
date("n",strtotime($order->created_at)),
date("Y",strtotime($order->created_at)),
ceil(date("m",strtotime($order->created_at))/3),
$order->reseller->name,
$order->creator,
$order->name,
));
}
}

// Auto filter for entire sheet
$sheet->setAutoFilter();
$sheet->freezeFirstRow();
// Set black background
$sheet->row(1, function($row) {

// call cell manipulation methods
$row->setBackground('#cccccc');
$row->setFontWeight("bold");

});
$sheet->setColumnFormat(array(
'G' => \PHPExcel_Style_NumberFormat::FORMAT_NUMBER_00,
'H' => '[$EUR ]#,##0.00_-',
'I' => \PHPExcel_Style_NumberFormat::FORMAT_NUMBER_00,
));

});

})->download('xlsx');;
}

Answer

It seems that you're trying to process too many processes at a same time which is taking so much of memory, you should use chunk() method of Laravel's collection like this:

Order::orderBy('created_at','desc')->chunk(10, function($orders)use ($sheet) {
    foreach($orders as $index => $order) {
        // Do your stuff here...
    }
}

Hope this helps!

Comments