0

I was wondering if someone could give me some pointers on how to create a download popup as well as a location for the user to save it.

So when they click on my "Download as CSV" button, it'll give the user a prompt to select a destination in their directory.

Currently, I'm able to get a file downloaded working, but it's only if I run it from my command line. I'm not too sure how to implement headers with this.

The main issue is because I can't use fopen(), fwrite(), and fclose() because I'm adding only a single (albeit BIG) string to the csv file.

Here's some code that works only if I run the program locally.

  $output = print_r(cleanUpEntry($info), true);
  file_put_contents("output.csv", $output);

It downloads the file to the same exact folder as my PHP file, but I need it to work on a webpage so that the user can download the file.

Note* I can't use fputcsv since it only works for arrays, and mine is a multidimensional array, so it's much easier to just get the output of print_r.

2 Answers 2

1

Send CSV file to the browser

$output = ...
header('Content-Type: text/csv');
echo $output;
exit;

Browsers tend to open files like CSVs, PDFs etc. To save the file instead of opening, add HTTP header Content-Disposition. For files larger few bytes, use Content-Length as well.

Force browser to download file.

$output = ...
$filename = "output.csv";
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header("Content-Length: " . strlen($output));
echo $output;
exit;

Send static file to the browser

Your web server (Apache, Nginx etc.) should handle static files, but in case you need to run it thru PHP for security or other reasons...

$file = './files/myfile.csv';
header('Content-Type: text/csv');
readfile($file);
exit;

Force browser to download a static file.

$file = './files/myfile.csv';
$filename = basename($file); // or specify directly, like 'output.csv'
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header("Content-Length: " . filesize($file));
readfile($file);
exit;
Sign up to request clarification or add additional context in comments.

4 Comments

For some reason, your "Force browser to download file." code gives me the following error: "Parse error: syntax error, unexpected ';', expecting ',' or ')' in line 63" (which is header(Content-Length: " . strlen($output);)
Ah, I've had a missing bracket typo. I've edited the answer, try now :)
Works like a charm! Thank you so much :)
I did, but don't have enough reputation for it to show yet.. it will show up once I reach 15
0

This uses old school fopen, fputcsv, and fclose, and not file_put_contents but always works for me...

    function csv_from_array($fileName, $data, $header_included = FALSE){
        // Downloads file - no return
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header('Content-Description: File Transfer');
        header("Content-type: text/csv");
        header("Content-Disposition: attachment; filename={$fileName}");
        header("Expires: 0");
        header("Pragma: public");
        $fh = @fopen( 'php://output', 'w' );
        foreach($data as $line) {
            // Add a header row if not included
            if (!$header_included) {
                // Use the keys as titles
                fputcsv($fh, array_keys($line));
            }
            fputcsv($fh, $line);
        }
        fclose($fh);
        exit;
    }

Do you need to use file_put_contents for some reason?

If the file already exists / doesn't need to be created from a php array, you can modify as below:

    function download_csv($fileName){
        // Downloads file - no return
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header('Content-Description: File Transfer');
        header("Content-type: text/csv");
        header("Content-Disposition: attachment; filename={$fileName}");
        header("Expires: 0");
        header("Pragma: public");
        exit;
    }

2 Comments

Like the note on the bottom says, I can't use fputcsv since that only works with arrays. In other words, foreach($data as $line) won't work. I have a multi-dimensional array that doesn't format nicely if I flatten it to a 1-D array, which is why I just get the output of print_r and save it using file_put_contents. Either way, the code that delta zero put down below works great!
Gotcha, that's why I added the second bit as well, once you have any file (print_r multidimensional saved to file) you can download it using that function. (same as delta zero's options) - either way, glad you got what you needed working!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.