PHP force download for PDF files
1 March 2009
It's quite often on a website that instead of letting someone view a file online, and letting the user see the file path of where it's being stored, you use a force download script which means that the user has to download the file instantly.
I do my force downloads in PHP using the header() function. There may be other ways, but not yet that I'm aware of.
You want to be careful when writing a force download script as it may enable someone to download any file on your web server including your PHP and server side script pages.
The best way is to send the page an id number that can then be looked up in an online database and then the database will hold the file path so that the user won't be able to see it.
Force downloading a PDF is slightly different from force downloading other files because relative and exact file paths will cause the PDF to not open and give a "File Corrupted" error.
The "Content-Type" header shows the file type that the page needs to render for.
Here's a list of the content types that could be used for the different file extensions when carrying out a force download:
switch( $file_extension )
{
case "pdf": $content_type="application/pdf"; break;
case "exe": $content_type="application/octet-stream"; break;
case "zip": $content_type="application/zip"; break;
case "doc": $content_type="application/msword"; break;
case "xls": $content_type="application/vnd.ms-excel"; break;
case "ppt": $content_type="application/vnd.ms-powerpoint"; break;
case "gif": $content_type="image/gif"; break;
case "png": $content_type="image/png"; break;
case "jpeg":
case "jpg": $content_type="image/jpg"; break;
default: $content_type="application/force-download";
}
?>
Here's the code to force download a PDF file:
$filename = $_SERVER['DOCUMENT_ROOT'] . "/path/to/file/my_file.pdf";
header("Cache-Control: public");
header("Content-Description: File Transfer");
header('Content-disposition: attachment; filename='.basename($filename));
header("Content-Type: application/pdf");
header("Content-Transfer-Encoding: binary");
header('Content-Length: '. filesize($filename));
readfile($filename);
?>
The "$_SERVER['DOCUMENT_ROOT']" isn't needed for every file, some file types allow you to just use exact and relative file paths, but a PDF will throw back "File Corrupted" errors if this is not used.
The PDF force download code can be used for all files, just change the "Content-Type" header to the content type for the file you want to force people to download.
http://www.peternichol.com/entry/trackback/37/
Please leave a comment using the form provided.






