Browser Directives for PDF Display or Download
When a PDF file is downloaded, the browser can handle the PDF in one of two ways:
-
Display the PDF in the browser.
(If downloaded via a link coded with an HTML
a
tag with thetarget="_blank"
attribute, the browser is directed to display the PDF in a new tab.) -
Save the PDF as a file.
The browser tends to follow the user's preferences when deciding how to handle the PDF download.
You can control how the browser handles the download, or at least have an illusion of control, when using a download link with a URL to a PHP script (source code further below). Example link:
<a href="http://example.com/download.php?mydoc.pdf" target="_blank"> Download PDF </a>
The download.php
script directs the browser to handle the mydoc.pdf
download according to the method coded in the script. (Coding for the methods is presented further below.)
The browser isn't required to follow your directive. Generally, however, it will.
Exceptions would be if the user has set a specific preference otherwise or there is reason it can not do so. Some reasons for not acceding to your preference may be lack of a hard drive (like on a driveless device), inability of the browser to render PDF, or the browser was programmed to dispose of PDF in only one way.
The PHP script uses the header() function to tell the browser how to handle the PDF download.
The trick to using the PHP header() function to download documents with a PHP script is that no content, not even a space or linefeed, may have been sent to the browser before the header() function is used. As soon as the download code has run, you exit the PHP script.
The Four Lines of Code
The PHP download.php
script contains four lines of code. The first two lines are calls to the header() function, the third is a call to the readfile() function, and the fourth line exits the script.
header(Content-Type: ...)
A header call to tell the browser the content type of the download.
header(Content-Disposition: ...)
A header call to tell the browser what to do with the download and the file name to suggest if the download is saved.
readfile(...)
The function that sends the content of the download to the browser.
exit;
Exit the script.
Following are three different versions of the PHP download.php
script. All assume you have a file on your server in the document root of your domain named mydoc.pdf
for downloading.
Download PDF to Display in Browser Window
These four lines will download a PDF file and tell the browser to display it in the browser window, then exit the PHP software. Notes follow.
header('Content-Type:application/pdf'); header('Content-Disposition:inline; filename="mydoc.pdf"'); readfile($_SERVER['DOCUMENT_ROOT'].'/mydoc.pdf'); exit;
There are four parts in the above code that need comment.
-
application/pdf
as the content type tells the browser that the file is a PDF file. -
inline
for content disposition tells the browser to display it inline (meaning in the browser window). -
mydoc.pdf
at the end of the content disposition line tells the browser that if the PDF is saved, then suggest to the user thatmydoc.pdf
is an appropriate file name. -
$_SERVER['DOCUMENT_ROOT'].'/mydoc.pdf'
is the location on the server of the file that is sent to the browser.
That's all the browser needs to know for displaying the PDF in the browser window and letting the user also save it as a file should they choose to do so.
(The file name for saving may be different than the name of the file being downloaded. In other words, filename="mydoc.pdf"
may be coded as filename="anothername.pdf"
)
Download PDF and Save PDF as a File
These four lines will download a PDF file and tell the browser to save the file, then exit the PHP software. Notes follow.
header('Content-Type:application/pdf'); header('Content-Disposition:attachment; filename="mydoc.pdf"'); readfile($_SERVER['DOCUMENT_ROOT'].'/mydoc.pdf'); exit;
Only the attachment for content disposition is different than when telling the browser to display the PDF in a window. But I'll comment on each item anyway in case you didn't give the other a close read.
There are four parts in the above code that need comment.
-
application/pdf
as the content type tells the browser that the file is a PDF file. -
attachment
for content disposition tells the browser to save the PDF as a file. -
mydoc.pdf
at the end of the content disposition line tells the browser that when the file is saved to suggest to the user thatmydoc.pdf
is an appropriate file name. -
$_SERVER['DOCUMENT_ROOT'].'/mydoc.pdf'
is the location on the server of the file that is sent to the browser.
That's all the browser needs to know for saving the PDF as a file. It might or might not do as you request, but it knows what you want.
Download PDF and Be Virtually Certain to Save It as a File
The previous method for causing a downloaded PDF document to be saved as a file generally works. When it doesn't, it almost certainly is because user preferences overrode your request.
It is generally a good idea to let the user override. It can be assumed they have a good reason for it. They may even be annoyed if you bypass it.
But if you must bypass any preferences that would override your request to save the PDF as a file, the following should do it. It's still not 100% certain, but probably somewhere around 99.999%.
header('Content-Type:application/octet-stream'); header('Content-Disposition:attachment; filename="mydoc.pdf"'); readfile($_SERVER['DOCUMENT_ROOT'].'/mydoc.pdf'); exit;
Only the application/octet-stream
for content type is different in this case. What you're doing is telling the browser to download a file and refusing to let it know what type of file it is. It is virtually certain that the the browser has no choice but to ask the user to save the file, with no options to open the file or display the file in the browser window.
As noted, only the first of these four parts was changed from the previous section.
-
application/octet-stream
as the content type tells the browser that you don't know what type of file it is. -
attachment
for content disposition tells the browser to save the file. -
mydoc.pdf
at the end of the content disposition line tells the browser that if the file is saved, then suggest to the user thatmydoc.pdf
is an appropriate file name. -
$_SERVER['DOCUMENT_ROOT'].'/mydoc.pdf'
is the location on the server of the file that is sent to the browser.
That's all the browser needs to know for saving a file that it has no idea what type of file it is.
As a note of interest, the application/octet-stream
file type can come in handy when writing software and you really don't know what kind of file the browser will be asked to download. File types can often be obtained by consulting the file name extension. But a weird extension could have been assigned, or no extension at all, or an extension that isn't consistent with the file type.
As you can see, file type application/octet-stream
can come in handy. But I generally don't recommend it when you do know what file type is being downloaded. It is included in this article for completeness, not as a recommendation.
You now know how to tell the browser whether a PDF file being downloaded is for display in the browser window or for saving as a file. When you study the code, you see there is very little difference between them.
(This article first appeared with an issue of the Possibilities newsletter.)
Will Bontrager