Gandalf
Gandalf

Reputation: 930

How to force download a file using PHP?

I would like the user to download a file when he/she clicks a 'download this file' link.

The use case: A user clicks a link, and the web app generates a file and "pushes" it as a download.

I have the following PHP code. Although the file is being generated correctly in the server, it is not being downloaded (and not showing the download dialog box).

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
readfile('file.zip');

I tried to add the following but it is not working:

header("Location: file.zip");  // not working

Although, I found a JavaScript solution (which is working), by trying the following redirect:

window.location.href = 'file.zip';

The problem is, doing the JavaScript thing above tries to "unload" the current window /form, which will not work for me in this situation.

Is there a solution to this using just PHP to "force" the file (in this case 'file.zip') to download?

Upvotes: 3

Views: 856

Answers (2)

Funk Forty Niner
Funk Forty Niner

Reputation: 74232

I have two examples that I use and work, well three actually.

HTML

<a href="save_file_1.php">Click here</a>

PHP (save_file_1.php)

<?php
$file = 'example.zip';

 if(!file)
 {
     die('file not found');
 }
 else
 {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));
        ob_clean();
        flush();
        readfile($file);
        exit;
 }
?>

And the second, which is short and sweet.

A dialog box will prompt the user to save to...

HTML

<a href="save_file_2.php">Click here</a>

PHP (save_file_2.php)

<?php
header('Content-Disposition: attachment; filename=example.zip');
readfile("example.zip");
?>

And a variant of the example just above:

<?php
$file = "example.zip";
header("Content-Disposition: attachment; filename=$file");
readfile("$file");
?>

All of which I have tested and working (for me) on a hosted server using PHP Version 5.4.20.

Upvotes: 1

user3126379
user3126379

Reputation:

$file_url = 'http://www.myremoteserver.com/file.exe';
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary"); 
header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\""); 
readfile($file_url); // do the double-download-dance (dirty but worky)

Also make sure to add proper content type based on your file application/zip, application/pdf etc. - but only if you do not want to trigger the save-as dialog.

Upvotes: 2

Related Questions