I'm trying to create a short PHP script that takes a JSON string, converts it to CSV format (using fputcsv
), and makes that CSV available as a downloaded .csv file. My thought was to use tmpfile()
to not worry about cronjobs or running out of disk space, but I can't seem to make the magic happen.
Here's my attempt, which is a converted example from the PHP docs of readfile
:
$tmp = tmpfile();
$jsonArray = json_decode( $_POST['json'] );
fputcsv($tmp, $jsonArray);
header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename='.basename($tmp));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($tmp));
ob_clean();
flush();
readfile($tmp);
I feel like the Content-Disposition
and Content-Transfer-Encoding
headers are wrong, but I'm not sure how to fix them. For example, basename($tmp)
doesn't seem to return anything, and I'm not sure text/csv
transfers as binary encoding. Likewise, echo filesize($tmp)
is blank as well. Is there a way to do what I'm attempting here?
[Edit]
**Below is the working code I wrote as a result of the accepted answer:*
$jsonArray = json_decode( $_POST['json'], true );
$tmpName = tempnam(sys_get_temp_dir(), 'data');
$file = fopen($tmpName, 'w');
fputcsv($file, $jsonArray);
fclose($file);
header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename=data.csv');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($tmpName));
ob_clean();
flush();
readfile($tmpName);
unlink($tmpName);