Friday 26 Sep 2008

Force to download .PDF

PHPWith some PDF reader software, including the most popular Adobe Acrobat Reader, the default setting is to open PDF files in the browser when we click on a link to a PDF.

As a webmaster you can force the browser dialog box allowing to choose to open it directly or to save it.. :-)

First, you must create a small PHP file with that:

<?php
if (file_exists ($_GET['f']))
{
  header('Content-type: application/force-download');
  header('Content-Disposition: attachment; filename=' . basename ($_GET['f']));
  readfile($_GET['f']);
}
else
{
  header('HTTP/1.0 404 Not Found');
  echo 'Error, this file does not exist.';
}
?>

What does this script? It sends a header saying the browser to force the download for this file, then the name to suggest in the dialog box, and finally it sends the file.

If the file does not exist, it returns a 404 error. The message can be embellished or even included in the design of your site. ;-)

I call this file _pdf.php. Then, we must call this file when we put a link to a PDF.


1st case, your server allow URL rewriting

It's the most simple, just add this or create a .htaccess file with this:

RewriteEngine on
RewriteRule ^(.*).pdf$ _pdf.php?f=$1 [L]

Instead of opening a file .pdf directly, it sends it to our _pdf.php file which will force the download.

2d case, your server does not allow address rewriting

That will be more tedious because you must rewrite by hand :-| your links to PDF. Instead of a link to file.pdf write :arrow: _pdf.php?f=file.pdf
PS: Be careful in this case because readfile() can send any other file, you must add a verification $_GET['f'] is a allowed type, or use _pdf.php?f=file and add the .pdf extension in PHP.

If you don't know in what case you are, just try the 1st, if it doesn't work you must choose te second solution.


cafĂ© Did this article help you? 
Buy me a coffee!

11 answers at “Force to download .PDF”

  1. 1
    Canon (filemount.com) said:

    Thanks.
    but can i force download a pdf file from external url?

  2. 2
    David (azure-dev.kizone.net) said:

    Yes, :-) with the first version. PHP is generally configured to allow distant readfile().

    The 'f' parameter has to be the entire URL:
    _pdf.php?f=http://.....

    The disadvantage is your server will receive the full PDF and retransfer it, so you will use bandwidth compared to a direct download.

  3. 3
    California Drug Rehab said:

    Wow. This Blog is truly a gold mine. I will actually try these tips and let you know how they work out! Thanks again mate.

  4. 4
    Abdul Awaes (awaes.com) said:

    Great! works perfect for me.. (I used 2d case "rewrite by hand"). %Thanks

  5. 5
    Sebastiaan de Jonge (sebastiaandejonge.com) said:

    This is a very unsafe of force downloading a file. There are no checks on the actual filename which would allow the user (by modifying the URL) to download any file on the server. Also your PHP files and possibly configuration files containing credentials to e.g. databases.

  6. 6
    David (azure-dev.kizone.net) said:

    You're right. The article focuses on the headers to send, but I will precise to be careful. I had not noticed that, thanks. ;-)

  7. 7
    ninyo said:

    my url is like this "test/test1/file.html" but its a pdf file i just rewrite it.

    now when i point it to the said url. i get HTML file not pdf file.

  8. 8
    David (azure-dev.kizone.net) said:

    How can you get a HTML file? :-| You also have one with that name? If yes, it's normal, it has the priority over the URL rewriting.

  9. 9
    Sebastiaan de Jonge (sebastiaandejonge.com) said:

    @ninyo: Try forcing the MIME-type header like this:

    header('Content-type: application/pdf');

  10. 10
    ninyo said:

    @David no, the path look like this http://samplesite.com/createpdf1-132.html

    for some security purposes i rewrite the .pdf file to .html BUT its a pdf file.
    having said that putting

    header('Content-type: application/pdf');

    now i get the .pdf file but i still have an error the content wasn't there any idea why?

  11. 11
    David (azure-dev.kizone.net) said:

    Verify the path and the permissions (755)... :-|

Azure Dev