knd
knd

Reputation: 1732

How to write PHP script for proper file download?

I have trouble shooting at file download problem. In Chrome, the download works fine. In Firefox, it generate some HTML headings at the end of file like:

<!DOCTYPE .....>
...
...

For some other browsers, the downloaded files miss some lines too. How do I write the script to actually make it work properly for many browser? Here is my current code:

private  function downloadRawFileHelper($file) {
    if (ini_get('zlib.output_compression')) {
        ini_set('zlib.output_compression', 'Off');
    }
    if (!file_exists($file)) {
        die('File Not Found');
    }

    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private", false);
    header("Content-Type: text/php");
    header("Content-Disposition: attachment; filename=\"". basename($file). "\"");
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: " . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    $this->view = 'fileedit';
}

Upvotes: 0

Views: 1665

Answers (5)

Julian Reschke
Julian Reschke

Reputation: 42075

The best way to debug HTTP problems is to actually inspect the HTTP message that is sent. Today's browsers make this really easy.

If the site is public, you can try redbot.org to check the response.

Finally, you are sending tons of undefined and/or useless response header fields, such as "Content-Transfer-Encoding", or the "check" directives in Cache-Control.

Upvotes: 0

luchopintado
luchopintado

Reputation: 939

here's your problem:

header("Content-Disposition: attachment; filename=\"". basename($file). "\"");

try to give a name for your archivo, for example:

header("Content-Disposition: attachment; filename=\"". basename($file). "filename.extension\"");

Upvotes: 0

Lusitanian
Lusitanian

Reputation: 11132

Before flush() add ob_end_clean(); and an exit() after readfile(). Also, you might consider using X-SendFile instead of pure PHP to send the file to the client, as that will tie up valuable resources in the case of large files.

Upvotes: 0

Sabeen Malik
Sabeen Malik

Reputation: 10880

Try putting an exit after readfile , I think that would solve your problem

Upvotes: 1

Sabari
Sabari

Reputation: 6355

I can't find any issue with the code. Can you try adding exit() or die() at the end of your function. Change it to:

private  function downloadRawFileHelper($file) {
    if (ini_get('zlib.output_compression')) {
        ini_set('zlib.output_compression', 'Off');
    }
    if (!file_exists($file)) {
        die('File Not Found');
    }

    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private", false);
    header("Content-Type: text/php");
    header("Content-Disposition: attachment; filename=\"". basename($file). "\"");
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: " . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    $this->view = 'fileedit';
    exit();
}

You are outputting the file to browser. So you need to stop script execution after that.

Hope this helps :)

Upvotes: 0

Related Questions