Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP readfile() adding extra bytes to downloaded file

Tags:

php

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

like image 460
jimmyjambles Avatar asked Nov 28 '22 22:11

jimmyjambles


2 Answers

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.

like image 130
Yanick Rochon Avatar answered Dec 06 '22 20:12

Yanick Rochon


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();
like image 22
Nifty Avatar answered Dec 06 '22 20:12

Nifty