header("Content-type: application/zip");
$contents=file_get_contents($the_file);
echo "$contents";
exit;
The file is about 40 MB. But, on downloading, size is only few hundred bytes. Please help!
Try to set Content-Length:
header('Content-Type: application/zip');
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename="file.zip"');
The comments are correct; it's very likely an error message that will be easily ascertained by opening the file in a text editor. I'd like to also offer that you could use the readfile function to greater effect. See the first example for some good code with headers that gives you a good download. Plus, it'll shorten your code by a line. http://php.net/manual/en/function.readfile.php
Related
I want to serve an existing file to the browser in PHP.
I've seen examples about image/jpeg but that function seems to save a file to disk and you have to create a right sized image object first (or I just don't understand it :))
In asp.net I do it by reading the file in a byte array and then call context.Response.BinaryWrite(bytearray), so I'm looking for something similar in PHP.
Michel
There is fpassthru() that should do exactly what you need. See the manual entry to read about the following example:
<?php
// open the file in a binary mode
$name = './img/ok.png';
$fp = fopen($name, 'rb');
// send the right headers
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));
// dump the picture and stop the script
fpassthru($fp);
exit;
?>
See here for all of PHP's filesystem functions.
If it's a binary file you want to offer for download, you probably also want to send the right headers so the "Save as.." dialog pops up. See the 1st answer to this question for a good example on what headers to send.
I use this
if (file_exists($file)) {
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);
exit;
}
I use readfile() ( http://www.php.net/readfile )...
But you have to make sure you set the right "Content-Type" with header() so the browser knows what to do with the file.
You can also force the browser to download the file instead of trying to use a plug-in to display it (like for PDFs), I always found this to look a bit "hacky", but it is explained at the above link.
This should get you started:
http://de.php.net/manual/en/function.readfile.php
Edit: If your web server supports it, using
header('X-Sendfile: ' . $filename);
where file name contains a local path like
/var/www/www.example.org/downloads/example.zip
is faster than readfile().
(usual security considerations for using header() apply)
For both my website and websites I create for clients I use a PHP script that I found a long time ago.
It can be found here: http://www.zubrag.com/scripts/download.php
I use a slightly modified version of it to allow me to obfuscate the file system structure (which it does by default) in addition to not allowing hot linking (default) and I added some additional tracking features, such as referrer, IP (default), and other such data that I might need should something come up.
Hope this helps.
Following will initiate XML file output
$fp = fopen($file_name, 'rb');
// Set the header
header("Content-Type: text/xml");
header("Content-Length: " . filesize($file_name));
header('Content-Disposition: attachment; filename="'.$file_name.'"');
fpassthru($fp);
exit;
The 'Content-Disposition: attachment' is pretty common and is used by sites like Facebook to set the right header
<?php
header('Content-disposition: attachment; filename=Booking.pdf');
header('Content-type: application/pdf');
readfile('http://mysite.com/Booking.pdf');
?>
why is the Booking.pdf file downloaded empty!??
mac and windows both say:
The file “Booking.pdf” could not be opened because it is empty.
checked google and stackoverflow, can't find relative info... has anyone experienced this before?
ps: I only found this forum post:'The online issue is a bit off topic I think, but is generally due to loading the PDF to a server in the ASCII mode of FTP rather than binary. That creates a corrupt file. Be sure to turn on binary transmission', but this is not true in this case as i can display the same pdf file in an iframe and it is not blank/empty.
You need to change
readfile('http://mysite.com/Booking.pdf');
To
readfile(__DIR__ . '/Booking.pdf');
Example
$file = __DIR__ . '/test.pdf' ;
header('Content-disposition: attachment; filename=Booking.pdf');
header('Content-type: application/pdf');
header("Content-length: ".filesize($file));
readfile($file);
I am trying to troubleshoot an issue I am having with downloading a "zip" file from a php script. It seems that when I download the file using the following code, the downloaded file has an extra 0A09 appended to the beginning of the file, causing winzip to throw a corruption error.
<?php
$pagePermissions = 7;
require_once ('util/check.php');
require_once ('util/file_manager.php');
$file_manager = new FileManager();
if ($_SERVER['REQUEST_METHOD'] == "GET") {
if (isset($_GET['q']) && $_GET['q'] == 'logout') {
//require_once ('util/users.php');
//$userdata = new Userdata();
$userdata -> kill_session();
header("Location: download.php");
exit ;
}
if (isset($_GET['q']) && $_GET['q'] == 'fetch') {
if (isset($_GET['name'])) {
#apache_setenv('no-gzip', 1);
header("Content-length: " . filesize('upload/' . $_GET['name']));
header('Content-type: application/zip');
//header("Content-Disposition: attachment; filename=\"{$_GET['name']}\" ");
header("Content-Disposition: attachment; filename={$_GET['name']}");
header('Content-Transfer-Encoding: binary');
readfile('upload/' . $_GET['name']);
exit();
}
}
}
?>
Any help would be greatly appreciated, the file downloads fine through a direct link, the appended 2 bytes to the beginning of the file occurs only thorough this code.
Thanks in advance
Remove the last ?> and check that your opening tag is on the very first line, at the very first character of your scripts. PHP files do not have to end with end tags. The reason why your downloaded files contain a (or more) \r\n is because PHP will directly echo (output) anything outside of <?php ?>. Usually, if you script does not echo HTML, you will omit the closing PHP tag as it is not mandatory and, IMO, yields more trouble than anything else.
** Edit **
If you read the PHP manual for readfile, you have a useful example, pretty much the code you have in your question, less two lines of code :
#apache_setenv('no-gzip', 1);
header("Content-length: " . filesize('upload/' . $_GET['name']));
header('Content-type: application/zip');
//header("Content-Disposition: attachment; filename=\"{$_GET['name']}\" ");
header("Content-Disposition: attachment; filename={$_GET['name']}");
header('Content-Transfer-Encoding: binary');
// add these two lines
ob_clean(); // discard any data in the output buffer (if possible)
flush(); // flush headers (if possible)
readfile('upload/' . $_GET['name']);
exit();
If you still have a problem after that, then the problem might not be with your PHP code.
Sorry for late reply.....
i don't know i am right until you vote this.....
edit your code as :
ob_start("");
//instead of ob_start(); with out a null callback
and
ob_end_clean(); //at the end , Note : "important" add instead of ob_end_flush()
ie;
ob_start("");
//header
ob_end_clean();
I ran into a similar issue today related to readfile(). It turns out my php.ini file has output compression enabled and that was messing up the flash module trying to retrieve the file. (I guess it couldn't handle it.)
All I had to do was the turn off the compression in the php.ini file:
zlib.output_compression = off
Or alternatively, in your script:
<?php ini_set('zlib.output_compression', 'Off'); ?>
Just want to share this in case someone else was having trouble receiving files from a readfile() output.
I had a similar problem in Joomla (2.5), using readfile to pass back Excel (.xls) files to the user.
I also noticed that the text and xml files also had some code inserted at the begining, but nearly ignored it because xml & text readers tended to open the files still.
I decided to try Yanick's suggestions (rather than playing with server compression options), simply flushing the buffer before readfile:
ob_clean(); // discard any data in the output buffer (if possible)
flush(); // flush headers (if possible)
Hey presto, it worked. I'm suggesting this as an alternative answer: to highlight the root cause, show it can fix a Joomla issue and because I had a mixture of binary and text returns.
Just to add (apologies if this is obvious!) - the mime type setting worked fine:
$document = JFactory::getDocument();
$document->setMimeEncoding($mimetype);
I did not even need to set 'Content-Transfer-Encoding: binary' when the mime type was to application/octet-stream.
I had same problem So I used this headers and I got my solution.
$filename = ABSPATH.'/wp-content/summary/user_content/'.trim($file);
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Description: File Transfer');
header('Content-Type: text/text');
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: max-age=0');
readfile($filename);
exit;
I had a similar issue with blank space at the start of an image file.
I suspect my issue was caused by blank space before opening
What worked for me was:
#ob_start(''); //# supresses a warning
//header entries
ob_end_clean();
ob_clean();
readfile($file);
I want to allow a user to download a pdf file, the download code is below....for some odd reason even though the file is being downloaded I get an error saying that the file has been damaged on the server...Could someone help me and point out where I am making my mistake.
<php
$name = $_POST["name_first"];
$mail = $_POST['email'];
$number = $_POST['phone_number'];
$email_message = "first name: {$name} email is {$mail} number is {$number} ";
mail('fanaa#gmail.com', 'Form Response', $email_message);
if ($mail == "" OR $name == "" OR $number == "")
{
echo "Enter valid details ";
}
else
{
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="tokina.pdf"');
readfile('docs/tokina.pdf');
}
?>
I used this code to download pdfs:
header ("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Type: application/octetstream');
header("Content-Transfer-Encoding: Binary");
header("Content-length: ".filesize($file));
header("Content-disposition: attachment; filename=\"".basename($filename)."\"");
readfile("$file");
}
This should be fine, and make sure there are no spaces or return characters (don't escape php at all is the best solution).
If you find your still having problems, open the corrupted file with notepad (there may be a php error warning inside).
Hope this helps!
Remove the headers and look at the page, do you see any error messages? If PHP outputs anything else than the actual PDF source, the file will appear to be corrupted.
header('Content-type: application/pdf');
enable PHP extension php_gettext and you are done.
try taking out the double quotes in
header('Content-type: "application/octet-stream"');
so it becomes
header('Content-type: application/octet-stream');
Maybe your content-type is not correct. try this one:
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="downloaded.pdf"');
readfile('original.pdf');
Your PDF file tokina.pdf is either not uploaded or not in the same directory as the PHP file. That's why it's saving as "tokina.pdf.htm" - it's loading the HTML for a 404 page instead. That is why your browser/PDF viewer thinks the file is "corrupted" - because its extension is PDF but its contents are not.
Make sure the file is uploaded, and if it is, make sure readfile is pointing to the correct path. If it's not in the same folder, use a relative/absolute path, for example:
readfile('docs/tokina.pdf');
And yes, the content type should be application/pdf
Using this script
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename='.$filename);
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($filenamepath));
readfile($filenamepath);
I had the same problem. Comparing the original file and the downloaded file with a hexadecimal editor like UltraEdit, I found some characters at the beginning of the corrupted file.
The problem was that after ?> marking end of PHP code there were line terminators several times in my code.
Remove all the line terminators after ?> and read also the forum article Downloaded Files are corrupt - Common Problem. That worked for me.
I hope that can help you.
I use
$download_path = your path (where to look for the files)
set_time_limit(0);
$file_url = $download_path . $data['link'];
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file_url). '"');
//then to read the file
readfile($file_url);
this usually works for me
i have a tar archive on the server that must be downloadable through php. This is the code that i've used:
$content=file_get_contents($tar);
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=$tar");
header("Content-Length: ".strlen($content));
unlink($name);
die($content);
The file is downloaded but it's broken and it can't be open. I think that there's something wrong with headers because the file on the server can be open without problems. Do you know how can i solve this problem?
UPDATE
I've tried to print an iframe like this:
<iframe src="<?php echo $tar?>"></iframe>
And the download works, so i'm sure that there's something missing in headers.
I have used this code when I have had to do it:
function _Download($f_location, $f_name){
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($f_location));
header('Content-Disposition: attachment; filename=' . basename($f_name));
readfile($f_location);
}
_Download("../directory/to/tar/raj.tar", "raj.tar");
//or
_Download("/var/www/vhost/domain.com/httpdocs/directory/to/tar/raj.tar", "raj.tar");
Try that.
Don't use file_get_contents() and then echo or print to output the file. That loads the full contents of the file into memory. A large file can/will exceed your script's memory_limit and kill the script.
For dumping a file's contents to the client, it's best to use readfile() - it will properly slurp up file chunks and spit them out at the client without exceeding available memory. Just remember to turn off output buffering before you do so, otherwise you're essentially just doing file_get_contents() again
So, you end up with this:
$tar = 'somefile.tar';
$tar_path = '/the/full/path/to/where/the/file/is' . $tar;
$size = filesize($tar_path);
header("Content-Type: application/x-tar");
header("Content-Disposition: attachment; filename='".$tar."'");
header("Content-Length: $size");
header("Content-Transfer-Encoding: binary");
readfile($tar_path);
If your tar file is actually gzipped, then use "application/x-gtar" instead.
If the file still comes out corrupted after download, do some checking on the client side:
Is the downloaded file 0 bytes, but the download process seemed to take much longer than it would take for 0 bytes to transfer, then it's something client-side preventing the download. Virus scanner? Trojan?
Is the downloaded file partially present, but smaller than the original? Something killed the transfer prematurely. Overeager firewall? Download manager having a bad day? Output buffering active on the server and the last buffer bucket not being flushed properly?
Is the downloaded file the same size as the original? Do an md5/sha1/crc checksum on both copies. If those are the same, then something's wrong with the app opening the file, not the file itself
Is the downloaded file bigger than the original? Open the file in notepad (or something better like notepad++ which doesn't take years to open big fils) and see if any PHP warnings messages, or some invisible whitespace you can't see in your script got inserted into the download at the start or end of the file.
Try something like the following:
$s_filePath = 'somefile.ext';
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'. s_filePath.'"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Cache-control: private');
header('Pragma: private');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header("Content-Length: ".filesize($s_filePath));
$r_fh = fopen($s_filePath,'r');
while(feof($r_fh) === false) {
$s_part = fread($r_fh,10240);
echo $s_part;
}
fclose($r_fh);
exit();
Use Content-Type: application/octet-stream or Content-Type: application/x-gtar
Make sure you aren't echoing anything that isn't the file output. Call ob_clean() before the headers