file force download - php

I want to force a download.. In IE I get an error but there are no problems in FF
header("Content-Type: application/force-download\n");
header("Content-Disposition: attachment; filename=test.txt");
echo 'test file';

I just googled about your curious application/force-download mime type. I dont know, who did "invented" this, but it seems, that it just dont exists. See http://mimeapplication.org/force-download.html
This means, the IE probably dont like it. Use application/octet-stream instead. As far as I remember firefox opens a download dialog for every mime-type, that is either registered with "show download dialog", or it simply doesnt know. In this case FF probably doesnt know the type.

This might help you , it works for me
header('Content-Type: application/force-download');
header("Content-disposition: attachment; filename=$filename");
flush();
readfile($filename);
exit;
you can add other headers if desired :)

Related

PHP send stream to browser as zip archive

I am making a call(PHP server) to an API and I can confirm that I am getting a response, my code at the point where I know I am getting a response is:
$binaryF = $rsObject->makeCall('get', "/JobData/{$_GET["jID"]}", "?format=bin");
//header("Pragma: public"); // required
//header("Content-Type: application/zip");
//header("Content-Disposition: attachment; filename=ss.zip");
//header("Content-Length: " . filesize($binaryF.length));
//header("Content-Transfer-Encoding: binary");
file_put_contents('C:\ss.zip', $binaryF);
If I keep the code as is and click on the link that takes me to the page with this code on it, ss.zip is created and I open it and confirm that it has the correct content. The data is coming from an API call on the first line and is basically a zip package. If I remove the comments and comment out the file_put_contents line then the browser opens a file save dialog box but if I save it the archive is 0 bytes?
How do I send the content to a browser after retrieving it from the api call? I do not want to save it to disk first, I want to send it to the browser making the request directly.
Thank you
Jack
Ok. I changed it to:
header("Pragma: public"); // required
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=ss.zip");
header("Content-Length: " . strlen($binaryF));
header("Content-Transfer-Encoding: binary");
and now it opens the file save. I save it and it is 8 K but when I try t oopen it I get a message of: "Windows cannot open the folder" It complains that the zip is invalid? At least I am getting somewhere, thanks for the help so far!
Try (untested):
header('Content-type: application/octet-stream');
header('Content-disposition: attachment; filename=ss.zip');
echo $binaryF;
$binaryF would need to be a string value for the filepath to the file you are trying to serve up in order for filesize() to work.
You can use strlen() to get the filesize for use in the ContentLength header.
You of course still need to actually output the file to the client browser.
I had some similar problems with PDF's, for me the Content-Length couldn't be calculated correctly with strlen() because it doesn't support multibyte-characters.
instead try this:
header("Content-Length: " . mb_strlen($binaryF));
See the documentation for more detailed information: http://www.php.net/manual/en/function.mb-strlen.php
Ok, #zerkms helped me by pointing out that I should use: strlen($binaryF) instead of filesize($binaryF.length) He helped me in a chat session by telling me to open the zip archive(with something simple like notepad) that I did get with file_put_contents('C:\ss.zip', $binaryF); This showed that what was produced was only partially correct, there was some HTML content that slipped into the response of the actual call. So all credit goes to #zerkms, thanks.
What worked? the following worked for me:
header("Pragma: public"); // required
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=ss.zip");
header("Content-Length: " . filesize($binaryF.length));
header("Content-Transfer-Encoding: binary");
echo $binaryF

Zip file downloads, but is invalid?

I use this code to enable users to download a zip file:
if(file_exists($filename)){
header("Content-Disposition: attachment; filename=".basename(str_replace(' ', '_', $filename)));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize($filename));
flush();
$fp = fopen($filename, "r");
while (!feof($fp))
{
echo fread($fp, 65536);
flush();
}
fclose($fp);
exit;
}
When the file is downloaded, it only downloads 25,632 kilobytes of data. However the zip file is 26,252 kilobytes ...
Why does the browser get all 25MB but then stop?
I checked the Content-Length header to make sure it was correct and it is...
edit
In firefox, when i download the file, it says 'of 25mb' SO the browser thinks that 25mb is the COMPLETE amount... however, the content-length when echo'd is 26252904?
add this before your code
ob_clean();
ob_end_flush();
Your header('Content-Type ...) calls are useless as only the last one will be sent to the browser.
Downloads are triggered by Content-Disposition: attachment. You should send the actual Content-Type: application/zip if you are sending a zip file.
Finally, your read loop is unnecessary.
Putting it all together, your code should look like this:
if (file_exists($filename)) {
$quoted_filename = basename(addcslashes($filename, "\0..\37\"\177"));
header("Content-Disposition: attachment; filename=\"{$quoted_filename}\"");
header('Content-Type: application/zip');
header('Content-Length: '.filesize($filename));
readfile($filename);
}
Use a single MIME type to represent the data.
In this case using application/octet-stream will do just fine. This is when you dont know the MIME before hand. When you know it, you must put it. Do not use multiple content-type headers.
Usually, when the browser doesn't know how to handle a particular MIME, it will trigger the download process. Further, using Content-disposition: Attachment; .. ensures it.
There exists a simple readfile($filename) which will send out the bytes of the file to the requesting process like below:
header("Content-disposition: attachment;filename=" . basename($filename);
readfile($filename);
I had similar problem. The file downloaded fine in Firefox but not in IE. It appeared that Apache was gzipping the files and IE was not able to ungzip so the files were corrupted. The solution was to disable gzipping in Apache. You can also check if PHP is not gzipping on the fly and disable it too.
For Apache you can try:
SetEnv no-gzip 1
And for PHP, in .htaccess:
php_flag zlib.output_compression on
This answer is by No means a REAL ANSWER.
However i did get it to work... I just set the Content-Length to 30000000. Therefor it thinks the file is bigger than it actually is, and then it downloads it all.
Ugly hack i know, but i couldn't find ANY other way

Utility of HTTP header "Content-Type: application/force-download" for mobile?

I am currently working on a PHP script that allows you to download media contents (video, audio, pictures...) from your mobile device by accessing a link. (i.e. http://www.my-web-site.com/download.php?id=7ejs8ap)
My script worked very vell when I was testing it with recent mobile (Samsung Galaxy S, iPhone 4S, some others...) but an error occured on my old mobile Samsung C3050. The media I wanted to download was just an audio mp3 file that I usually download easily.
The error appears to be "Unknown content type."
So, as my only HTTP header Content-Type was "application/force-download", I try to comment this and try again. Then, it works.
But now, I am currently asking what this Content-Type means and if it can be mandatory for others mobile. I tested without the Content-Type on the iPhone 4 and it works, but I'm not sure of this compatibility for all mobile.
Can someone explain me how that Content-Type works, why this isn't a standard MIME or everything else that can help me to be sure this is an optionnal Content-Type for every download, whatever the file, the browser or the device I am downloading on?
Thanks everyone.
Here is my PHP headers sent:
<?php
//Assume that $filename and $filePath are correclty set.
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="'.$filename.'"');
// header('Content-Type: application/force-download'); Non-standard MIME-Type, incompatible with Samsung C3050 for example. Let it commented
readfile($filePath);
?>
EDIT : I just tried with a Sony Xperia, and the download wasn't successful: I only see the "html-encoded" bytes of my file I want to download.
How can I know what content-type I have to use if application/octet-stream or application/force-download doesn't work?
Content-Type: application/force-download means "I, the web server, am going to lie to you (the browser) about what this file is so that you will not treat it as a PDF/Word Document/MP3/whatever and prompt the user to save the mysterious file to disk instead". It is a dirty hack that breaks horribly when the client doesn't do "save to disk".
Use the correct mime type for whatever media you are using (e.g. audio/mpeg for mp3).
Use the Content-Disposition: attachment; etc etc header if you want to encourage the client to download it instead of following the default behaviour.
To download a file please use the following code ... Store the File name with location in $file variable. It supports all mime type
$file = "location of file to download"
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
To know about Mime types please refer to this link: http://php.net/manual/en/function.mime-content-type.php
application/force-download is not a standard MIME type. It's a hack supported by some browsers, added fairly recently.
Your question doesn't really make any sense. It's like asking why Internet Explorer 4 doesn't support the latest CSS 3 functionality.

Retrieving output from a url. How do I force the dowload of a PDF from a url using php

I need to retrieve our reports from the jasperserver report engine as a PDF, then I want the PDF to be forced as a download, instead of being displayed inthe browser. The problem with displaying in the browser is we don't want the report parameters to be displayed to the end users in the url.
If I enter this URL path into the browser I get a PDF document that shows in the same browser window with all the report data:
https://mysite.com:8443/jasperserver/flow.html?_flowId=viewReportFlow&reportUnit=sample_report&output=pdf;
What I would prefer to have happen is for a download dialog box to be used and for the users to download the PDF to their computer, instead of it showing in the browser.
I've tried the following php code, but can't get it to work. I get a return value of false, but nothing in the server logs that shows an error.
ob_start();
header("Location: $src"); /* Redirect browser */
$report_contents = ob_get_contents();
ob_end_clean();
var_dump($report_contents);
I'm not really sure how to go about this...anyone got any ideas?
Thanks for the help.
You could buffer the file to the PHP server then output with force download:
header('Content-disposition: attachment; filename=huge_document.pdf');
header('Content-type: application/pdf');
readfile('https://mysite.com:8443/jasperserver/flow.html?_flowId=viewReportFlow&reportUnit=sample_report&output=pdf;');
See the notes about using readfile over an HTTP stream wrapper
http://php.net/manual/en/function.readfile.php
how about
$source=$url
header("Expires: 0");
header("Cache-Control: private");
header("Pragma: cache");
header("Content-length: $size");
header("Content-type: $type");
header("Content-Disposition: attachment; filename=$name");
readfile($source);
exit();

Showing generated PDF problem

I have a problem with showing generated PDF. The pdf is saved in dataBase. I'm continuing work of a guy that started work that way, so I need to work that way. There's no problem with saving the file on computer,it's working fine, but I need to show it in new window when it's read from dataBase...
And sorry about my English. :)
<?
$pdf=pdf_new();
pdf_open_file($pdf,"");
pdf_begin_page($pdf,600,800);
$font=pdf_findfont($pdf,'Helvetica-Bold','host',0);
pdf_setfont($pdf,$font,30.0);
pdf_show_xy($pdf,"Sample Text",50,600);
pd_set_parameter($pfd,"openaction","fitpage");
pdf_close($pdf);
$buf=pdf_get_buffer($pdf);
$len=strlen($buf);
header("Content-Type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=sample.pdf");
echo $buf;
pdf_delete($pdf);
?>
More information and some code example would be helpful.
You'll need to set the correct header before outputting to the window.
header('Content-type: application/pdf');

Categories