1

I use a really memory intensive function to generate a csv export file from diffrent SQL tables and values. When i choose a dataset where is to large, than i get this error:

OutOfMemoryException in PDOStatement.php line 105:
Error: Out of memory (allocated 1636040704) (tried to allocate 12788 bytes)

I was looking for some ideas to fix it and found the following sources:

php.ini: memory_limit= '256M'

I did this fix, but it didnt helped me.

as well i found the following tip:

config/monolog:buffer_size: 200

but it also did not help me..

further i tried to disable the profiler...and nothing became better!

Has somebody an another idea? how i can fix this error without to refactor the methods and the sql queries.

The following function represents this funtion:

public function exportAction(Request $request){ 

//profiling data    
//$stopwatch = new Stopwatch();
//$stopwatch->start('Period');

if ($this->container->has('profiler'))
{
$this->container->get('profiler')->disable();
}


$data = $this->get('session')->get('dataE');
$data = unserialize($data);

$em = $this->getDoctrine()->getManager();

// restrict search result by user rights
if ($data['mnds'] == '1' || ($this->get('security.context')->isGranted('ROLE_EPO') && !$this->isAdmin())) {
    $data['registry'] = 1;
} elseif ($data['asp'] == '1' || ($this->get('security.context')->isGranted('ROLE_ASP') && !$this->isAdmin())) {
    $data['registry'] = 2;
}

// Load data structure
$repo = $em->getRepository('DataLiveBundle:DataZImportStructure');
$qb = $repo->getExportQuery($data);
$dStruct = $repo->getResults($qb);

$selectFields = array();
$tableNames = array();

foreach($dStruct as $ds) {
  $selectFields[] = $ds->getPrefix() . "." . $ds->getName();
  $tableNames[] = $ds->getSqlname();
}

//profiling data 
//$stopwatch->lap('Period');

// search data
$repo = $em->getRepository('DataLiveBundle:DataAPatient');
$dataTable = $repo->getDataExport($data, $selectFields);

// compile data
$rows = array();
$rows[0] = implode(';', str_replace(array(";", "\n"), '_', array_slice($tableNames, 0, -1)));

//$event = $stopwatch->stop('Period');
//$response = new Response("<h1>Hello World</h1>".$event->getDuration()." ms  ".$event->getMemory()." memory");

foreach ($dataTable as $row) {
  $cleanRow = array();
  foreach ($row as $entry) {
    if (is_numeric($entry)) {
      $cleanRow[] = $entry;
    } elseif (is_string($entry)) {
      $entry = str_replace(array(";", "\n"), '_',$entry);
      $cleanRow[] = preg_replace("/[\n\r]/","",$entry);
    } elseif (is_a($entry, 'DateTime')) {
      $cleanRow[] = $entry->format('d.m.Y');
    } else {
      $cleanRow[] = $entry;
    }
  }
  $rows[] = implode(";", array_slice($cleanRow, 0, -1));
}


$rawData = implode("\n", $rows);

// prepare csv 
$response = new Response($rawData);

//$response = new Response("<h1>Hello World</h1>".$event->getDuration()." ms  ".$event->getMemory()." memory");
$response = new Response($rawData);
//$response->headers->set('Content-Length', filesize($rawData));
$response->headers->set('Content-Type', 'text/csv');

return $response;

}

Thanks for your time!

helmi
  • 130
  • 2
  • 14
  • Which line is line 105 where the error occurs? You have `$response = new Response($rawData);` twice in there. – Adder Mar 09 '18 at 09:52
  • 1
    The number `(allocated 1636040704)` tells me you have not successfully change the memory limit to `256M` Check you edited the correct `php.ini` file. There are normally 2, One for your web server and one for PHP CLI. Also make sure you restarted your web server after amending the Correct `php.ini` – RiggsFolly Mar 09 '18 at 09:53
  • Use the symfony profiler to locate the time gap. remove redundant code like "$response = new Response($rawData);" And you can alternative setup your php.ini with unlimit memory limit like : "memory_limit= '-1'" – episch Mar 09 '18 at 10:53
  • Thanks to you.. I really had only to change the memory_limit size in all ini files and not just in one! After change it everywhere it works without some troubbles! – helmi Mar 09 '18 at 11:15

0 Answers0