PHP readfile() 导致文件下载损坏

2022-01-02 00:00:00 download file-io php

我正在使用 php 脚本在必要的 javascript 计时器之后从我的网站提供下载,此 php 脚本包含在其中,导致下载.但是无论我尝试什么,下载的文件都已损坏.谁能帮我指出我哪里出错了.

I am using php script to provide download from my website after a requisite javascript timer this php script is included which causes the download. But the downloaded file is corrupt no matter whatever I try. Can anyone help me point out where am I going wrong.

这是我的代码

     <?php
include "db.php";    
 $id = htmlspecialchars($_GET['id']);
 $error = false;
    $conn = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
    if(!($conn)) echo "Failed To Connect To The Database!";
    else{   
        if(mysql_select_db(DB_NAME,$conn)){
            $qry = "SELECT Link FROM downloads WHERE ID=$id";
            try{
                $result = mysql_query($qry);
                if(mysql_num_rows($result)==1){
                    while($rows = mysql_fetch_array($result)){
                        $f=$rows['Link'];
                    }
                    //pathinfo returns an array of information
                    $path = pathinfo($f);
                    //basename say the filename+extension
                    $n = $path['basename'];
                    //NOW comes the action, this statement would say that WHATEVER output given by the script is given in form of an octet-stream, or else to make it easy an application or downloadable
                    header('Content-type: application/octet-stream');
                    header('Content-Length: ' . filesize($f));
                    //This would be the one to rename the file
                    header('Content-Disposition: attachment; filename='.$n.'');
                    //Finally it reads the file and prepare the output
                    readfile($f);
                    exit();
                }else $error = true;
            }catch(Exception $e){
                $error = true;
            }
            if($error) 
            {
                header("Status: 404 Not Found");
                }
        }
  }
?> 

推荐答案

首先,正如一些人在评论中指出的那样,删除 PHP 开始标记之前的所有空格 (<?php) 在第一行,这应该可以解决问题(除非其他文件包含或需要此文件).

First of all, as some people pointed out on the comments, remove all spaces before the opening PHP tag (<?php) on the first line and that should do the trick (unless this file is included or required by some other file).

当您在屏幕上打印任何内容时,即使是单个空格,您的服务器都会发送标题以及要打印的内容(在这种情况下,您的空格).为防止发生这种情况,您可以:

When you print anything on the screen, even a single space, your server will send the headers along with the content to be printed (in the case, your blank spaces). To prevent this from happening, you can:

a) 在写完标题之前不要打印任何东西;

a) not print anything before you're done writing the headers;

b) 运行 ob_start() 作为脚本中的第一件事,编写内容,编辑标题,然后在您希望将内容发送到用户浏览器时运行 ob_flush() 和 ob_clean().

b) run an ob_start() as the first thing in your script, write stuff, edit your headers and then ob_flush() and ob_clean() whenever you want your content to be sent to the user's browser.

在 b) 中,即使您成功写入标头而没有出错,空格也会损坏您的二进制文件.你应该只写你的二进制内容,而不是二进制内容的几个空格.

In b), even if you successfully write your headers without getting an error, the spaces will corrupt your binary file. You should only be writing your binary content, not a few spaces with the binary content.

ob_ 前缀代表输出缓冲区.当调用 ob_start() 时,你告诉你的应用你输出的所有东西(echoprintf 等)都应该保存在内存中,直到你明确地告诉它去"(ob_flush())到客户端.这样,您将输出与标题一起保存,当您完成编写它们时,它们将与内容一起发送.

The ob_ prefix stands for Output Buffer. When calling ob_start(), you tell your application that everything you output (echo, printf, etc) should be held in memory until you explicitly tell it to 'go' (ob_flush()) to the client. That way, you hold the output along with the headers, and when you are done writing them, they will be sent just fine along with the content.

相关文章