PHP readfile()导致文件下载损坏 [英] PHP readfile() causing corrupt file downloads

查看:205
本文介绍了PHP readfile()导致文件下载损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用php脚本来提供从我的网站下载一个必要的JavaScript定时器,这个php脚本被包含导致下载。但下载的文件是破坏,无论我尝试什么。任何人都可以帮我指出我哪里错了。



这是我的代码

 code><?php 
includedb.php;
$ id = htmlspecialchars($ _ GET ['id']);
$ error = false;
$ conn = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
if(!($ conn))echo无法连接到数据库!;
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返回一个信息数组
$ path = pathinfo($ f);
// basename说文件名+扩展名
$ n = $ path ['basename'];
//现在是动作,这个声明会说脚本给出的WHATEVER输出是以八位字节流的形式给出的,或者是使应用程序或者可以下载的
头文件('Content -type:application / octet-stream');
header('Content-Length:'。filesize($ f));
//这将是重命名文件
header('Content-Disposition:attachment; filename ='。$ n。')的文件。
//最后它读取文件并准备输出
readfile($ f);
exit();
} else $ error = true;
} catch(Exception $ e){
$ error = true;
}
if($ error)
{
header(Status:404 Not Found);
}
}
}
?>


解决方案

首先,有些人指出注释,在第一行打开PHP标签(<?php )之前删除所有空格,并且应该做的伎俩(除非这个文件被其他一些包含或要求文件)。



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



a)在完成头文件之前不打印任何内容;



b)运行一个ob_start()作为脚本中的第一件事情,写东西,编辑头文件,然后在想要将内容发送到用户的浏览器时使用ob_flush()和ob_clean()。



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



ob _ 前缀代表Output Buffer。当调用 ob_start()时,您可以告诉应用程序您输出的所有内容( echo printf应该在内存中保存,直到你明确地告诉客户端去去( ob_flush())。这样,您将输出与标题一起保存,当您完成写入操作时,它们将随内容一起发送。


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.

This is my code

     <?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");
                }
        }
  }
?> 

解决方案

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) not print anything before you're done writing the headers;

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.

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.

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.

这篇关于PHP readfile()导致文件下载损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆