Direcly outputting to a CSV from an array without saving to a CSV file
arrays, csv, file, php
Solution
$array = [
['name', 'email'],
['Doe, John', 'johndoe@foo'],
['Jane Doe', 'janedoe@foo'],
['Ron "SuperFly" O\'Neal', 'supafly@foo'],
];
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=test.csv");
$fp = fopen('php://output', 'w'); // or use php://stdout
foreach ($array as $row) {
fputcsv($fp, $row);
}
see fputcsv()
The benefit of using `fputcsv` is it will handle escaping and enclosing of fields for you, ensuring valid, rugged output that will never break even if your columns values happen to contain csv control characters such as commas, quotes, newline characters etc... If you don't take care to handle control characters robustly, and instead take a common shortcut such as using `implode(',', $row)` your (low quality) code will produce broken csv output.
Unfortunately, fputcsv cant output to a string, only to a stream, so I write to php's output stream via `php://output` which is equivalent to `echo`'ing it out. Note that just like output via echo, it will go through php's output buffer mechanism, and that includes any possible output handlers, such as `ob_gzhandler` or customer output buffer callback functions that may modify the output. If you wish to bypass the output buffer, you can instead write directly to `php://stdout`.
You could also write to `php://memory`, `php://temp`, or a file if you need to access the csv file contents as a string before outputting it.
$fp = fopen('php://memory', 'w+'); // or php://temp
foreach ($array as $row) {
fputcsv($fp, $row);
}
// Read it back into a string, if desired.
// Rewind the stream to start.
fseek($fp, 0);
// Read the entire stream back to string.
$csvContents = stream_get_contents($fp);
info on stream wrappers http://www.php.net/manual/en/wrappers.php.php
Problem
I am looking for a simple way to take an array, turn it into a CSV and have a user be able to download the CSV, all without saving the CSV to the server.