Php下载脚本输出损坏的文件

时间:2015-11-26 20:36:03

标签: php download http-headers

我在PHP中为我的CMS构建了一个文件下载类,我注意到它以不同的编码格式输出文件。我尝试使用readfile,file_get_contents,fread,但似乎都在做同样的事情。这就像是与输出缓冲有关的东西。

我使用脚本下载的png格式的示例图像文件似乎在使用notepad ++从UTF更改为ASCII后编码

这是我到目前为止采取的步骤:

$mime = http::get_file_mime();
header('Pragma: public');   
header('Expires: 0');       
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private',false);
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Transfer-Encoding: binary');
header('Transfer-Encoding: binary');
header('Content-Description: File Transfer');
header('Content-Encoding: chunked');
header('Connection: closed');
@readfile($this->file);

我确实感到害怕:

$file = fopen($this->file,'r');
$read = fread($file,filesize($this->file));
print($read);

我做了file_get_contents();

$read = file_get_contents($this->file);
print($read);

所有这些步骤都将文件发送到下载对话框。但它不会按原样输出文件。这会影响我尝试使用脚本下载的任何文件。

我做错了什么?

2 个答案:

答案 0 :(得分:0)

尝试运行ob_start()作为脚本中的第一件事,编写内容,编辑标题,然后ob_flush()ob_clean(),只要您希望将内容发送给用户&# 39;浏览器。

这对我有用..

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, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
}

希望这会有所帮助..

答案 1 :(得分:0)

问题在于Content-Disposition标题。此标头实际上不是HTTP协议的一部分,请参阅RFC 2616, 15.5 Content-Disposition Issues

  

内容 - 处置不属于      HTTP标准,但由于它被广泛实施,我们是      记录其对实施者的使用和风险。

稍后在19.5.1 Content-Disposition

部分
  

Content-Disposition response-header字段已被提议为      表示如果用户,原始服务器建议默认文件名      请求将内容保存到文件中   ...
  一个例子是

Content-Disposition: attachment; filename="fname.ext"
  

如果在使用application / octet-的响应中使用此标头 -      流内容类型,隐含的建议是用户代理      不应该显示响应,而是直接输入“保存响应”      作为...'对话。

退出此标题会显示已发送文件的内容。

我仅使用Firefox对此进行了测试,因此其他网络浏览器可能会有所不同。