Home » Php » php – Header download file is corrupted

php – Header download file is corrupted

Posted by: admin July 12, 2020 Leave a comment

Questions:

I’m trying to download files via headers from my database. I’m not sure why my downloaded files are all corrupted when I change my download code to one that uses OOP but are fine when my code is non-OOP.

This is where I get the file id and call the download function:(handleDownload.php)

if (isset($_GET['id'])) {
        $id = $_GET['id'];
        //pump id into function getDBFiles to pull file with matching id
        $fileData = $Download->getDBFiles($id);
        header('Content-Type:"' . $fileData[2]. '"');
        header('Content-Disposition: attachment; filename="' . $fileData[1]. '"'); 
        echo $fileData[0];
        exit;
      }

This is the function that pulls the file from the database (download.php)

public function getDBFiles($id) {
            global $database;
            $sql = "SELECT * FROM ".self::$table_name." WHERE resume_id ='" . $id . "'";
            $result = $database->query($sql);
            if ($row = $result->fetch_array(MYSQLI_ASSOC)) {  
                $name = $row['resume_title'];
                $type = $row['file_type'];
                $content = $row['resume_data']; //content of file
                //$size = $row['file_size']; //file size
                return array($content, $name, $type);
            }
        }
 $Download = new Download();
 $download =& $Download;

The code works fine if it’s all in one page as shown below though:

if (isset($_GET['id'])) {
    $id = $_GET['id'];
    mysqli_select_db($con, "apples");

    $query = "SELECT * FROM resume where resume_id ='" . $id . "'";
    $result = mysqli_query($con, $query) or die('Error, query failed');


    if ($row = $result->fetch_array(MYSQLI_ASSOC)) {
        $name = $row['resume_title'];
        $type = $row['file_type'];
        $content = $row['resume_data']; //content of file
        $size = $row['file_size']; //file size
        header('Content-Type:"' . $type . '"');
        //header('Content-length:"' . $size . '"');
        header('Content-Disposition: attachment; filename="' . $name . '"');
        //var_dump($row);
        echo $content;
    }
}

UPDATE:
I’m now getting a download file is corrupted instead of a blank file. This is how the same file is outputted by the different download codes. The one on top is from the OOP code while the other is from the working non-OOP version.
hex comparison

This is my download code in its entirety.

try {
    //execute retrieval of files from database
    $Download-> showDBFiles();
    //pass results to output array 
    $output = $Download->getMessages();
    //if id is set then get file from database
    if (isset($_GET['id'])) {
        $id = $_GET['id'];
        //pump id into function getDBFiles to pull file with matching id
        $fileData = $Download->getDBFiles($id);
        header('Content-Type:"' . $fileData[2]. '"');
        header('Content-Disposition: attachment; filename="' . $fileData[1]. '"'); 
        echo $fileData[0];
        die();
      }
} catch (Exception $e) {
    $result[] = $e->getMessages();
}

After calling the functions, I would then echo out the output (the download links) with a foreach loop

<h2>Output</h2>
<?php if ($output) { ?>
<ul class="result">
    <?php
    foreach ($output as $message) {
        $id = $message['id'];
        $name = $message['name'];
        ?>
    <li><a href="handleDownload.php?id=<?php echo $id; ?>"><?php echo $name; ?></a></li>

    <?php }
?>
</ul>
How to&Answers:

In your non-OOP solution check for leading whitespaces inside the php file.

The following code would produce a corrupted file because of a leading whitespace.

 <?php
if (isset($_GET['id'])) {...

This also applies to whitespaces after the closing php tag (which you should not use).

Those chars will be submitted by your browser, included in the download stream and corrupt the whole file.