Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create CSV in memory, email, and remove from memory

Tags:

file

php

memory

private function convert_to_csv($input_array, $output_file_name, $delimiter) {

    $temp_memory = fopen('php://memory','w');

    foreach ($input_array as $line) {

        fputcsv($temp_memory, $line, $delimiter);

    }

    fseek($temp_memory, 0);

    header('Content-Type: application/csv');
    header('Content-Disposition: attachement; filename="' . $output_file_name . '";');

    fpassthru($temp_memory);

}               

I use the above function to take an array of data, convert to CSV, and output to the browser. Two questions:

  1. Is the file removed from memory after being downloaded via HTTP?
  2. How would this same function be rewritten such that the file could be used (for example, to use as an email attachment sent with PHPMailer) and then removed from memory immediately afterwards?

EDIT: Working Code - But writes to file, not memory

public function emailCSVTest() {

    $test_array = array(array('Stuff','Yep'),array('More Stuff','Yep yep'));

    $temp_file = '/tmp/temptest.csv';

    $this->convertToCSV($test_array, $temp_file);

    $this->sendUserEmail('Test Subject','Test Message','[email protected]',$temp_file);

    unlink($temp_file);

}

private function convertToCSV($input_array, $output_file) {

    $temp_file = fopen($output_file,'w');

    foreach ($input_array as $line) {

        fputcsv($temp_file, $line, ',');

    }

    fclose($temp_file);

}

Still unanswered: does the original function remove the file from memory, or no?

like image 842
FurryWombat Avatar asked May 28 '15 15:05

FurryWombat


1 Answers

I would make use PHP's temp fopen wrapper together with threshold of memory like this:

// we use a threshold of 1 MB (1024 * 1024), it's just an example
$fd = fopen('php://temp/maxmemory:1048576', 'w');
if ($fd === false) {
    die('Failed to open temporary file');
}

$headers = array('id', 'name', 'age', 'species');
$records = array(
    array('1', 'gise', '4', 'cat'),
    array('2', 'hek2mgl', '36', 'human')
);

fputcsv($fd, $headers);
foreach($records as $record) {
    fputcsv($fd, $record);
}

rewind($fd);
$csv = stream_get_contents($fd);
fclose($fd); // releases the memory (or tempfile)

The memory treshold is 1MB. If the CSV file get's larger, PHP would create a temporary file, otherwise all will happen in memory. The advantage is that large CSV files won't exhaust the memory.

About your second question, fclose() will release the memory.

I once wrote a blog article regarding to this, you may find it interesting: http://www.metashock.de/2014/02/create-csv-file-in-memory-php/

like image 170
hek2mgl Avatar answered Oct 13 '22 18:10

hek2mgl