I'm using database query in PHP to retrieve a binary file. But when I'm trying to force download it, the header('Content-type: application/octet-stream') line cause 0 byte files. Without that line I can download the file with full content. It's a binary file that's for sure so I just can't understand why that line causes the problem. The code:
$result = mysql_query("SELECT data FROM stored_file WHERE file_name = '$q'");
while($row = mysql_fetch_array($result))
{
$file = $row['data'];
}
header('Content-disposition: attachment; filename='.$q);
header('Content-type: application/octet-stream');
header('Content-Length: '.filesize($file));
header("Pragma: no-cache");
header("Expires: 0");
echo $file;
Any idea? Thanks.
The application/octet-stream MIME type is used for unknown binary files. It preserves the file contents, but requires the receiver to determine file type, for example, from the filename extension. The Internet media type for an arbitrary byte stream is application/octet-stream .
APPLICATION/OCTET-STREAM stands for binary data. It may be more precise by specifing the actual filetype. For images it coud be image/png . If the browser knows the exact filetype it may show the file directly.
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".
filesize()
won't return a meaningful value.
You have binary data in $file
, not an actual filename as required as first parameter. Hence you would get an error. (Enable error_reporting! Not seeing errors, and not having them are two different things.)
So what you want to use there is strlen($file)
, not filesize()
.
Btw, application/octet-stream
or other fill-ins have no use for forcing downloads. It's the Content-Disposition:
header which is most crucial to that effect. You're still allowed to send the correct MIME type.
From looking at the query I guess that in $row['data']
is the binary data stored. To set the correct Content-Length header you should use mb_strlen($row['data']);
. If no multibyte support (the mb_ functions) is activated on your machine, use strlen(). But be aware, this may result in akward results because the binary data could actually contain the EOF byte sequence and return a too short length. With the mb_strlen function you are on the save side.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With