views:

1478

answers:

5

I have a CSV file on my server, if a user clicks on a link it should download, but instead it opens up in my browser window.

My code looks as follows

 <a href="files/csv/example/example.csv" class="pagination">Click here to download an example of the "CSV" file</a>

It's a web server normal webserver where I have all of my dev work on.

I tried someting like

 <a href="files/csv/example/csv.php" class="pagination">Click here to download an example of the "CSV" file</a>

NOW the contents of my csv.php file:

header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');

Now my issue is it's downloading but not my CSV file it's creating a new file.

+4  A: 

Configure your server to send the file with the media type application/octet-stream.

Gumbo
+11  A: 

to brute force all csv's on your server to download you could add this to your .htaccess file:

AddType application/octet-stream csv

EDIT (an inline solution within your php file would be more like this):

header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');
readfile("/path/to/yourfile.csv");
seengee
Better use `readfile` instead of `echo file_get_contents`.
Gumbo
yep my bad, readfile is less intensive in this context
seengee
Why not just change the Content-Type line to `Content-Type: application/octet-stream` ? It seems a bit redundant to do it in an .htaccess when you're overriding it anyway.
R. Bemrose
that was the inital answer to the question, the question then changed so the second part was the answer to that.
seengee
A: 

This means, that your browser can handle this file type.

If you don't like it, the easiest method would be offering zip files. Everyone can handle zip files and they are downloadable by default.

StampedeXV
+7  A: 

This cannot be done reliably, since it's up to the browser to decide what to do with an URL it's been asked to retrieve.

You can suggest to the browser that it should offer to "save to disk" right away by sending a Content-disposition header:

header("Content-disposition: attachment");

I'm not sure how well this is supported by various browsers. The alternative is to send a Content-type of application/octet-stream, but that is a hack (you're basically telling the browser "I'm not telling you what kind of file this is" and depending on the fact that most browsers will then offer a download dialog) and allegedly causes problems with Internet Explorer.

Read more about this in the Web Authoring FAQ.

Edit You've already switched to a PHP file to deliver the data - which is necessary to set the Content-disposition header (unless there are some arcane Apache settings that can also do this). Now all that's left to do is for that PHP file to read the contents of the CSV file and print them - the filename=example.csv in the header only suggests to the client browser what name to use for the file, it does not actually fetch the data from the file on the server.

Michael Borgwardt
Using "Content-disposition: attachment" has worked consistently for us in all FF versions, IE6 and IE7.
Steve Claridge
A: 

Here is a more browser-safe solution:

    $fp = @fopen($yourfile, 'rb');

    if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
 header('Content-Type: "application/octet-stream"');
 header('Content-Disposition: attachment; filename="yourname.file"');
 header('Expires: 0');
 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
 header("Content-Transfer-Encoding: binary");
 header('Pragma: public');
 header("Content-Length: ".filesize($yourfile));
}
else
{
 header('Content-Type: "application/octet-stream"');
 header('Content-Disposition: attachment; filename="yourname.file"');
 header("Content-Transfer-Encoding: binary");
 header('Expires: 0');
 header('Pragma: no-cache');
 header("Content-Length: ".filesize($yourfile));
}

fpassthru($fp);
fclose($fp);
Franz