Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
33
rated 0 times [  37] [ 4]  / answers: 1 / hits: 15327  / 15 Years ago, thu, december 10, 2009, 12:00:00

I am working on a website where the visitor should be able to download a pdf file.
(There are three links to choose from but that is irrelevant)
I wanted to know how to make it so that the visitor can simply click the link and not have to



right click > Save (target) As...


I am open to PHP and or Javascript solutions. Thanks.



EDIT: Can I use javascript to call the PHP and save the file via AJAX?



EDIT2: I used Nirmal's solution in the end, since it was the simplest to change for all three files. I didn't need to make 3 files for the three PDF's and I didn't need to hand code the switch. BalusC gets the check though since his/her code was up first and does the trick too.


More From » php

 Answers
16

All you basically need to do is to set the Content-Disposition header to attachment to get a 'Save As' dialogue. Here's a kickoff PHP example:



<?php
header('Content-Type: application/pdf');
header('Content-Disposition: attachment;filename=foo.pdf');
readfile('/path/to/foo.pdf');
?>


You can't and don't want to do this with Javascript.



Important note: due to a poor feature, in MSIE the default filename in 'Save As' dialogue won't be derived from the content-disposition header, it will instead be the last part of the pathinfo in the request URL. To workaround this, append the PDF filename to the link, e.g. http://example.com/pdf/foo.pdf. You can even make use of it in PHP to read the in the pathinfo specified PDF file. Here's a basic example of pdf.php:



<?php
$file_name = $_SERVER['PATH_INFO'];
$file = '/path/to/pdf/files' . $file_name;
if (file_exists($file)) {
header('Content-Type: application/pdf');
header('Content-Disposition: attachment;filename=' . basename($file_name) . '');
header('Content-Length: ' . filesize($file));
readfile($file);
} else {
header('HTTP/1.1 404 Not Found');
}
?>


This however assumes that you've MultiViews on so that /pdf/ will go through this PHP file, or at least a RewriteRule from /pdf/ to /pdf.php/.



The major advantage of this approach is that you don't need to change the code whenever you want to add a new PDF file or change the PDF file name.



You can even make it more generic by automatically determining and setting the correct content type:



<?php
$file_name = $_SERVER['PATH_INFO'];
$file = '/path/to/all/files' . $file_name;
if (file_exists($file)) {
header('Content-Type: ' . mime_content_type($file_name));
header('Content-Disposition: attachment;filename=' . basename($file_name) . '');
header('Content-Length: ' . filesize($file));
readfile($file);
} else {
header('HTTP/1.1 404 Not Found');
}
?>


Name it files.php or so and then you have a generic PHP downloader which you can access by for example http://example.com/files/foo.pdf, http://example.com/files/bar.zip, etcetera.



Hope this helps.


[#98106] Monday, December 7, 2009, 15 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
ira

Total Points: 298
Total Questions: 112
Total Answers: 103

Location: Guadeloupe
Member since Sat, Aug 22, 2020
4 Years ago
;