How to make fputcsv "echo" the data
Asked Answered
W

4

38

I need a way to make the fputscv function write data to the browser on-the-fly instead of creating a temporary file, saving data into that file and doing a echo file_get_contents().

Whorish answered 14/1, 2011 at 15:32 Comment(0)
W
53

Found this on the PHP docs website, first comment under the function reference:

function outputCSV($data) {
  $outstream = fopen("php://output", 'w');
  function __outputCSV(&$vals, $key, $filehandler) {
    fputcsv($filehandler, $vals, ';', '"');
  }
  array_walk($data, '__outputCSV', $outstream);
  fclose($outstream);
}

And a second option:

$csv = fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');
fputcsv($csv, array('blah','blah'));
rewind($csv);

// put it all in a variable
$output = stream_get_contents($csv);

Hope this helps!

BTW the PHP docs should always be your first stop when trying to figure things out. :-)

Werra answered 14/1, 2011 at 15:34 Comment(5)
the outputCSV() from the PHP website doesn't work, did you even test this at all?Creativity
I answered this question 4+ years ago, maybe something has changed? I can't honestly say if I tried it or not, but I suspect I would have. Feel free to expand on what exactly isn't working instead of your empty reply with no detail, and maybe I'll look into it further.Werra
@VladimirGhetau I've just tested this particular one posted here by Seb Barre and it worked ... You must provide correct data though - it expects already parsed CSV into an array of arrays [[], [],...] ! @SebBarre the inner function could be just defined outside .... ANYWAY: I've added some constants and the simulation: ideone.com/giN5qWHorsewoman
Warning: rewind(): stream does not support seekingUella
Upvote for 'output', not 'stdout'Orit
I
30

By a comment on the PHP site

<?php
$out = fopen('php://output', 'w');
fputcsv($out, array('this','is some', 'csv "stuff", you know.'));
fclose($out);
?>
Intemerate answered 14/1, 2011 at 15:37 Comment(1)
For writing to a variable: php.net/manual/en/function.fputcsv.php#74118Lur
D
7

As the original asker wanted to "write to the browser on the fly", maybe is worth noting (as was my case and noone mentioned it) that if you want to force a file name and a dialog asking to download a file in the browser, you must set the proper headers before outputting anything with fputcsv:

header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=myFile.csv');
Dolor answered 6/5, 2015 at 10:10 Comment(3)
Thank you, this is what I want to do 90% of the time when outputting a CSV to a browser, and you saved me the time of looking this up separately.Tachistoscope
This goes horribly when your page somehow gets a crash and the output is HTML stack trace in the CSV file, especially when opening it in your favorite CSV editor causes it to hang or crash.Uella
@Uella it's your duty to avoid displaying any debug or error tracing output when on a production environment; adding HTML decoration to it even further worsens things. Also, if your favorite app doesn't know how to properly handle a malformed file and it even makes it to crash, not only you should blame that piece of crap, but you probably should change to a different software. But, in any case, if there's an error when generating the file, you shouldn't be sending any content to the browser at all. Blaming the one who told you the right headers for sending content is... surrealDolor
P
1

Producing a CSV is actually not all that difficult (parsing a CSV is a little bit more involved).

Sample code for writing a 2D Array as CSV:

$array = [
    [1,2,3],
    [4,5,6],
    [7,8,9]
];

// If this CSV is a HTTP response you will need to set the right content type
header("Content-Type: text/csv"); 

// If you need to force download or set a filename (you can also do this with 
// the download attribute in HTML5 instead)
header('Content-Disposition: attachment; filename="example.csv"')

// Column heading row, if required.
echo "Column heading 1,Column heading 2,Column heading 3\n"; 

foreach ($array as $row) {
    $row = array_map(function($cell) {
        // Cells containing a quote, a comma or a new line will need to be 
        // contained in double quotes.
        if (preg_match('/["\n,]/', $cell)) {
            // double quotes within cells need to be escaped.
            return '"' . preg_replace('/"/', '""', $cell) . '"';
        }

        return $cell;
    }, $row);

    echo implode(',', $row) . "\n";
}
Proterozoic answered 9/2, 2019 at 22:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.