PHP Readfile() Adding Extra Bytes to Downloaded File

PHP readfile() adding extra bytes to downloaded file

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.

PHP: Downloaded binary file gets an additional byte (0x0a) at the end

You most likely have an extra blank line after the closing ?>, which is being echoed with the data. The closing ?> is always optional at the end of a PHP file. Leaving it out is a good practice to prevent this sort of problem.

The reason the Content-Length changes is because the HTTP server (or PHP?) is ignoring it and adding a new one to match the actual data response before it gets sent it to the browser, so I think you can just leave that out. (If you do manage to send data with the wrong Content-Length, I've found browsers can act very weird.)

How to add extra data at the end of downloading content in PHP

Store your extra bytes in a file,variable,db or etc , and echo it after read file function

$file = 'monkey.gif';

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');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
readfile("extra_filename.ext");
/*
//or use this
$extra_bytes = "store extra bytes here";
echo $extra_bytes;
*/
exit;
}

readfile returns additional digit

http://php.net/manual/en/function.readfile.php

readfile() automatically echos the file's contents, so you don't need to use echo.

readfile() also returns an int and that's the 3 you are seeing.

Change your code to this.

<html>
<body>
<h1>My first PHP page</h1>
<?php
readfile("/home/pi/test/hx711py/export.txt", "r");
?>
</body>
</html>

Prepend bytes to file before download

It's possible, of course.

Now this depends on how you are serving the files. If you link directly to the files you will have to create a rewrite rule in your web server, that will pass the requested file to your PHP script[1]. The script will then output your "prependtext" along with the contents of the file. Don't forget to add appropriate HTTP headers[2]!

If you are already serving the files trough a PHP script then you jut need to output your "prependtext" before you output the contents of the file.

Remarks:

[1] To do so memory efficient with large files, use readfile()

[2] For text files the most important header is Content-type: text/plain (also see documentation for header() and readfile())

(PHP) Problem with filename after downloading it

Your code is not well-formed, you miss to escape double-quotes by adding single-quotes as I done here, please test my answer.

<?php
$filepath = "/www/servermedia/technounion.mp4";
$filename = basename($filepath);
header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename="' . $filename . '"');
readfile($filename);
exit;
?>

But I suggest a more complex way:

<?php
$filepath = $_SERVER['DOCUMENT_ROOT'] . "/www/servermedia/technounion.mp4";
$filename = basename($filepath);
header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . sprintf("%u", filesize($filepath)));
set_time_limit(0);
$fh = fopen($filepath, "rb");
while (!feof($fh)) {
echo fgets($fh);
ob_flush();
flush();
}
fclose($fh);
exit;
?>

$_SERVER['DOCUMENT_ROOT'] is useful to get the full path from the server

set_time_limit(0) is useful to avoid any timeout during download

fgets() is useful for reading large files

ob_flush() and flush() assure that there is not other output in the buffer

I hope this helps.



Related Topics



Leave a reply



Submit