Go directly to the browser. Do not pass GO, do not collect $200

Recently I needed to provide a simple CSV export function which allowed users to download some dynamic data. I wanted to use PHPs inbuilt fputcsv function so I didn't have to think about formatting but I didn't need to write it to disk. Instead I wanted to stream the content directly to the browser.

We can do this using PHP stream wrappers:

$fileHandle = fopen('php://output', 'w');

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

fclose($fileHandle);

This writes the content directly to the output buffer which is then sent to the browser. This skips all disk activity and keeps only 4K of the CSV in RAM (see ini_get('output_buffering')), no matter how big the export.

The only downside to this approach is that you can't set the Content-Length header. This is because it's impossible to know ahead of time how large the download is going to be until it is completely written. This will mean that users don't get a progress bar when downloading the file.

Popular Reads

Subscribe

Keep up to date

Please provide your email address
Please provide your name
Please provide your name
No thanks