Im trying to get a website to have a button that forces a download of a pdf.
Heres the html of the button:
<a href=scripts/download.php>
<input type="image" src="images/download.gif" alt="Submit button"/>
</a>
And the php script so far:
<?php
header('Content-Type: application/pdf');
header('Content-disposition: attachment;filename=documents/ECM_IT_ResumeDownload.pdf');
readfile('documents/ECM_IT_ResumeDownload.pdf');
?>
This seems to download the file fine but when I go to open it i get this error:
"Adobe Reader could not open 'documents_ECM_IT_ResumeDownload.pdf' because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded)."
Any help would be greatly appreciated.
EDIT
Opened the pdf in a text editor and got this message:
"
Warning: readfile(documents/ECM_IT_ResumeDownload.pdf) [function.readfile]: failed to open stream: No such file or directory in html/scripts/download.php on line 4
"
The document is definitely there though. in html/documents/ECM_IT_ResumeDownload.pdf
$file_url = www.example.com/pdffolder/$pdfname;
header('Content-Type: application/pdf');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=".$pdfname);
readfile($file_url);
Try removing the path to the file and just leave the file name in the content:
header('Content-Type: application/pdf');
header('Content-disposition: attachment; filename=ECM_IT_ResumeDownload.pdf');
Have you tried getting rid of the closing PHP tag (the ?>) at the end? It will treat the page as a pure PHP page, removing any possible new lines that might accidentally get appended to the end of the output. This helped me when I was dynamically creating excel files for download, and they were downloading as corrupted. Check out this page for more information:
http://www.php.net/manual/en/language.basic-syntax.phptags.php
From your edited question, it seems like PHP is unable to find the file. Try using an absolute path to the file like so: "c:\blah\de\blah\bloo.pdf" or "c:/blah/de/blah/bloo.pdf". If one of those paths works and downloads correctly, your relative path is incorrect in some way.
I always use Gowon Patterson's download script, it also has hotlink protection:
http://by.gowondesigns.com/getfile/
By the way, a bit late, but to identify the problem properly here:
Your download script is at scripts/download.php and the file you want to download is at documents/[...].pdf.
Therefore, your readfile() function should be traversing to the parent directory (outside of scripts/), e.g. readfile('../documents/[...].pdf');.
Related
I am saving a pdf file, and then attempting to download it using php.
The script seemed to work fine, but all of the sudden not anymore.
Can anybody see what I am missing?
PS: the file I am downloading is only 4.3kb big, so I assume that would be because it is not downloading at all. The actual file size should be bigger than this.
$pdf->output(ROOTDIR.'/modules/addons/statement_generator/reports/statement.pdf');
if($action=='print'){
$file_name = 'statement.pdf';
$file_url = "http://".$_SERVER['SERVER_NAME']."/modules/addons/statement_generator/reports/" . $file_name;
header('Content-Type: application/pdf');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
exit;
}
The $pdf->output() call will already send the PDF to the client. The file will not be saved to your local folder (Didn't you checked at least this?) because you have to pass "F" as the snd parameter.
After that you try to read from an URL (!!!!) that does not exists and which maybe return a nicely styled 404 html response. Two issues here:
Why are you using http when you have the local path used some lines above? Use the local path only!
The content returned by the URL is append to the already send PDF which ends in a document mixed of PDF and HTML (the 404 response) -> corrupted PDF
Conclusion: Use "F" as the 2nd parameter and use the same path for both writing and reading and not a mix of local path and URL.
I have a file with no extension on it, but I know it's a tiff. I want to be able to download this file via PHP.
I created a page with a link to another php page, which has the following content:
<?php
$imgPath = 'http://server/23700-b074137f-eb5c-45d6-87c2-13c96812345b';
header("Content-disposition: attachment; filename=invoice.tiff");
header("Content-type: image/tiff");
readfile($imgPath);
?>
When I click the link, I get a prompt to download invoice.tiff, but it's 0 bytes.
However, if I rename the file on the server to 23700-b074137f-eb5c-45d6-87c2-13c96812345b.tiff (and change the $imgPath), it works.
How do I accomplish this without renaming the file to include the extension?
It's possible the 'tiff' extension is registered as a known file type on the server, so when you rename and request the tiff it's permissions will allow you to open it. However, with no extension, the security is probably stopping you from reading it, as mentioned by 'Mike B' above. To check this try just entering the file name in your browser address bar and see if it opens, both with and without the 'tiff' extension. There is no workaround for getting past the security issue, short of changing the severs security which would be very bad.
You are retrieving the file from a URL, therefore activating the 'fopen wrappers' in readfile. In general, you should not do this, especially when working locally since it invokes a lot of unnecessary overhead and (in this case) unwanted 'magic' behaviour.
Just use readfile on the local path to the file, and it'll be fine, or use die(file_get_contents($imgPath)) instead of the last line to circumvent PHP's native behaviour.
It works for me:
$imgPath = 'http://server/23700-b074137f-eb5c-45d6-87c2-13c96812345b';
$f = fopen($imgPath, "r");
header("Content-disposition: attachment; filename=invoice.tiff");
header("Content-type: image/tiff");
fpassthru($f);
You should also add the content-length header like so:
// untested code
header('Content-Length: '.strlen(stream_get_contents($imgPath)));
well I'm just wondering how I can get an mp3 download to start instantly, as oppose to it simply starting to play in the browser when you directly go to it.
Preferably using php headers.
So essentially when you click the file, I want a download box to appear saving save etc. Right now it just opens and starts playing in the browser.
Thanks
You'll need to create a PHP file that "redirects" to the MP3 file, and point your links to that PHP file.
Code as below:
<?php
header('Content-type: audio/mpeg');
header('Content-Disposition: attachment; filename="fileName.mp3"');
readfile('originalFile.mp3');
?>
Note: The line that sets the Content-Disposition header is the critical one.
This question is for those who have used PHP library FPDF (http://www.fpdf.org ) to generate PDF documents using PHP. I am generating a PDF file using the php file 'my_file.php'. I want users to be able to download that PDF file. But in the browser the see the file in the address bar as ..somepath..../my_file.php . I want them to see it as a file with .pdf extension. Any idea how this can be done ?
when you create the object and then try to make output like this
$filePath = "files/cache/myPdf.pdf";
$pdf=new FPDF('p');
...
$pdf->Output($filePath,'I');
you can change and send the file name
To force download:
$pdf->Output('D'); //Force download and set filename as 'doc.pdf'
or setting your own filename:
$pdf->Output('MyFilename.pdf','D');
Your browser shall not open another tab whit yourpath/my_file.php
You can't change the browser address bar, but you can change the address on your server. For example if you're using Apache, there's mod_rewrite which allows you to do such things.
If your problem is that when downloading the file, the browser wants to save it as .php, you could use those headers to force the download and a filename.
header('Content-Type: application/octet-stream');
header('Content-Length: ' . FILESIZE_HERE);
header('Content-Disposition: attachment; filename=' . FILENAME.pdf_HERE);
I have a dynamic image which uses GD to throw in some overlay images/text. This would be dynamicImage.php?firstName=Bob&lastName=Sacamano. I want to be prompted to download that file, so I created a download.php file to act as the middle-man:
//Get the Arguments
$file .= "firstName=".filter_var($_GET['firstName'], FILTER_SANITIZE_STRING);
$file .= "&lastName=".filter_var($_GET['lastName'], FILTER_SANITIZE_STRING);
//get The File Size
$size = intval(sprintf("%u", filesize($file)));
//Header Info to Prompt for Download and name it a .jpg
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-disposition: attachment; filename=dynamicImage.jpg");
header("Content-Length: ".$size);
readfile($file, true);//.$file);
There's 2 problems, first I get this error:
PHP Warning: filesize() [<a href='function.filesize'>function.filesize</a>]: stat failed for dynamicImage.php?firstName=bob&lastName=Sacamano in /www/download.php on line 19
PHP Warning: readfile(dynamicImage.php?firstName=bob&lastName=Sacamano) [<a href='function.readfile'>function.readfile</a>]: failed to open stream: No such file or directory in /www/download.php on line 25
See how it parses the & to & ? But not only that. If I take out the arguments and just leave dynamicImage.php it prompts me to download the raw php file. Is there a way I can make it Run the PHP and then download the generated image?
BTW My dynamicImage.php ends with:
header("Content-Type: image/JPEG");
ImageJpeg ($bg);
imagedestroy($bg);
Fixd. I altered my dynamicImage.php thusly:
if(isset($_GET['download'])){
header('Content-Description: File Transfer');
header('Content-Type: application/octet-image');
header("Content-disposition: attachment; filename=dynamicImage.jpg");
}else{
header("Content-Type: image/JPEG");
}
ImageJpeg ($bg);
imagedestroy($bg);
I'll try to add some meat to my comment in an initial answer.
Trying to download your file through a separate call to another script over http is backwards and over complicating a simple problem.
It would be easier to refactor your original code for dynamicImage.php into a function. Then include that file as a library in download.php and use the function from dynamicImage.php to return your image with Content-disposition headers set.
Or you could add download as a third argument to your dynamicImage.php script and just add the Content-Disposition header to output form dynamicImage.php when that argument is set.
Also see #Novikov's answer.
How is the file called on your hard disk? That's the value you should filesize() on.
You are trying to call a PHP script from within a PHP script through HTTP? Very Rube Goldbergy.
You'll probably want a full path such as http://yoursite/dynamicImage.php, otherwise the PHP file handling functions will treat it as a filesystem call not an HTTP wrapper call.
The PHP manual states that stat isn't supported on HTTP wrappers so you won't be able to do filesize("http://url").
I'd suggest refactoring the code in dynamicImage.php so that for example &action=download will let you download the image as a file rather than a jpeg.
I think you only got 2 solutions :
Generate the picture the first time with your dynamicImage.php and store it into your server as, for example, bob-Sacamano.jpg. But it'll be a hdd space eater if you got a lot of pictures to generate, still, it's a solution.
As Novikov and many other said, you may want to generate and forcing download in the same script. (Maybe with another argument in your get http call like suggested).