Click here to Skip to main content
15,888,527 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I need a little help here. I intended to create 2 csv files in PHP and have the browser download them. This will happen when users click a button. However, I discovered that only 1 file download is permitted for each http request. I stumbled upon this stackoverflow post. The solution creates 3 csv files in-memory and added them into a zip file and download it to the client's browser.

I tried the solution marked as correct, but it didn't work. A zip file was downloaded, but it is empty.

What I have tried:

// some data to be used in the csv files
$headers = array('id', 'name', 'age', 'species');
$records = array(
    array('1', 'gise', '4', 'cat'),
    array('2', 'hek2mgl', '36', 'human')
);

// create your zip file
$zipname = 'file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);

// loop to create 3 csv files
for ($i = 0; $i < 3; $i++) {

    // create a temporary file
    $fd = fopen('php://temp/maxmemory:1048576', 'w');
    if (false === $fd) {
        die('Failed to create temporary file');
    }

    // write the data to csv
    fputcsv($fd, $headers);
    foreach($records as $record) {
        fputcsv($fd, $record);
    }

    // return to the start of the stream
    rewind($fd);

    // add the in-memory file to the archive, giving a name
    $zip->addFromString('file-'.$i.'.csv', stream_get_contents($fd) );
    //close the file
    fclose($fd);
}
// close the archive
$zip->close();


header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);

// remove the zip archive
// you could also use the temp file method above for this.
unlink($zipname);
Posted
Updated 30-Apr-18 9:30am
Comments
Richard MacCutchan 30-Apr-18 7:46am    
You need to close the .csv file when you have finished writing it, in order to get the content into the zip archive.
Member 12541933 30-Apr-18 8:36am    
I assume that I did ?

fclose($fd);

Or am I doing it wrong ?

1 solution

PHP
fopen('php://temp/maxmemory:1048576', 'w');

It creates a write-only stream! Use 'w+' the be able to read too...
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900