1

I am currently working on a utility that pulls files out of an MSSQL database. The body of the files are stored in the database as base64 string which I am decoding with the PHP function base64_decode(). To begin the file to download when the page opens I am using the headers:

$filename = $file[0][0];
$file_body = base64_decode( $file[0][1] );
$size = $file[0][2];
$type = $file[0][3];

header("Expires: 0"); 
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Content-Description: File Transfer");
header("Content-Length: $size;");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Type: $type "); 
header("Content-Transfer-Encoding: binary");

echo $file_body;

Files download and everything works perfect until the file size is over about 48kb. After that only 48kb of the file is downloaded. I have tested using many files types and still have the same result. I have boosted php memory and post size in php.ini at the suggestion of other posts I have found online, still no luck.

I realize PHP may not be the best way to accomplish this, however, this is what I have available to me.

Any ideas how I can ensure a complete file is always downloaded?

Brayden
  • 11
  • 3
  • 1
    Can you share the code you are actually creating the file to send it through php? – Jorge Campos Jan 04 '16 at 16:51
  • @JorgeCampos Updated with the requested code. – Brayden Jan 04 '16 at 19:08
  • are you running with error_reporting(E_ALL); ? and verify that the size of the decoded string actually is exactly what you expect. put: if(strlen($file_body)!==$size){throw new RuntimeException("corrupted data from db! file is supposed to be ".$size." bytes, but is only ".strlen($file_body)." bytes!");} – hanshenrik Jan 04 '16 at 19:12
  • @hanshenrik If I print out the decoded string to the screen it matches what I uploaded. If I use the file size I am pulling from the database it never seems to match the string length. Maybe it has been rounded? – Brayden Jan 04 '16 at 21:30
  • Some quick poking around and found a couple of maybe helpful links: http://stackoverflow.com/a/11316004/278763 and http://php.net/manual/en/function.readfile.php . I realize your not reading a file but are streaming contents, but maybe those might help. Do you need to `flush()` something after the `echo` call? – Peter Tirrell Jan 05 '16 at 21:59
  • @PeterTirrell I tried adding `flush()` and didn't have any luck. It corrupts the file and it can not be opened. – Brayden Jan 05 '16 at 23:56
  • Still no luck :( Any other ideas? – Brayden Jan 28 '16 at 23:09

1 Answers1

0

You don't need to store length (size) anywhere. You should calculate it on the fly in the following way:

$size = strlen($file_body);
...
header("Content-Length: $size;");
Stalinko
  • 3,319
  • 28
  • 31