Query to CSV Force File Download

i have a php function that I use to write a mysql query result to a csv file that is downloadable. It works fine on my local dev machine but when I move it to my website server instead of prompting for a download it throws the results into a webpage. I think it has to do with the way the function sets up the headers but I don’t know php very well. Will someone take a look at this code and give me any ideas why it acts differently when not on my local server?

/* These functions setup the headers:  */
function setExcelContentType() {
        return false;

    header('Content-type: application/vnd.ms-excel');
    return true;

function setDownloadAsHeader($filename) {
        return false;

   header('Content-disposition: attachment; filename=' . $filename);

    return true;

… and then some code to send the csv to a stream and write it to a file and then…

/* And this is where the magic happens */

function csvToExcelDownloadFromResult($result, $showColumnHeaders = true, $asFilename = 'data.csv') {
    return csvFileFromResult('php://output', $result, $showColumnHeaders);

Try setting the download header before setting the content type and see if that makes any difference.

You could also try setting the MIME type to CSV instead of excel.

Thank you for the suggestions. I tried both and to no avail. It seems that there is a setting on the server that ignores my custom headers or something. Any other suggestions out there?

So I used the Firefox plugin Live HTTP headers to try and see what was going on. Here are the results from my local machine.

HTTP/1.1 200 OK
Date: Wed, 12 May 2010 22:15:00 GMT
Server: Apache/2.2.14 (Win32) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Content-Disposition: attachment; filename=data.csv
Keep-Alive: timeout=5, max=97
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/csv

And this is the results from running it on the web server…

HTTP/1.0 200 OK
Date: Wed, 12 May 2010 22:12:43 GMT
Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.7a mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/
X-Powered-By: PHP/5.2.12
Content-Type: text/html
X-Cache: MISS from KRYTEN.logistics.int
X-Cache-Lookup: MISS from KRYTEN.logistics.int:8080
Via: 1.0 KRYTEN.logistics.int:8080 (squid/2.6.STABLE5)
Proxy-Connection: close

along with the disposition it didn’t set are the cause of your problem - now you just need to figure out why your attempt to set different values aren’t working.

I don’t know where to go from here. Does anyone know if there are server side settings that might override my headers I set using php?

EDIT: continued here http://www.sitepoint.com/forums/showthread.php?t=676775