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

Php下载脚本输出损坏的文件,php,download,http-headers,Php,Download,Http Headers,我正在用PHP为我的CMS构建一个文件下载类,当时我注意到它以不同的编码格式输出文件。我尝试了readfile、file\u get\u contents和fread,但似乎都在做同样的事情。这就像是与输出缓冲有关的东西 在使用notepad++将编码从UTF更改为ASCII后,我使用脚本下载的png格式的示例图像文件似乎可以正常工作 以下是我迄今为止采取的步骤: $mime = http::get_file_mime(); header('Pragma: public'); header

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

在使用notepad++将编码从UTF更改为ASCII后,我使用脚本下载的png格式的示例图像文件似乎可以正常工作

以下是我迄今为止采取的步骤:

$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);
我确实归档了内容()

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


我做错了什么?

尝试运行
ob\u start()
作为脚本中的第一件事,编写内容,编辑标题,然后
ob\u flush()
ob\u clean()
,无论何时您希望将内容发送到用户的浏览器

这是我的工作

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;
}

希望这对您有所帮助。

问题在于
内容配置
标题。此标题实际上不是HTTP协议的一部分,请参阅

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

在后面的章节中

内容处置响应标头字段已建议作为 表示源服务器建议默认文件名,如果用户 请求将内容保存到文件中。

例如

如果此标头用于带有应用程序/八位字节的响应中- 流内容类型,暗示用户代理 不应显示响应,但应直接输入“保存响应” 作为“对话”

省略此标题将显示已发送文件的内容


我只在Firefox上测试过这一点,因此其他web浏览器的行为可能会有所不同。

标题中应该有什么?请尝试更改此…
标题(“内容类型:应用程序/octet流”);标题(“连接:保持活动”)或标题(“连接:关闭”);
是否添加了
ob_start()
ob clean()
ob_flush()
?我之前就这么做了。与此同时,在我的CMS后端,相同的下载类工作得非常好。好吧,我遇到了一个与ob_start()相同的问题和其他功能。您是否比较了这两个文件可能是您缺少了什么。Ajay我刚刚尝试了。我用一个图像文件测试了它。下载的图像无法查看。@WebICTByLeo您可能想将此注释移动到Ajay的答案。是否与输出缓冲区有关?不,这不是缓冲区问题。正如我已经写过的,删除
Content Disposition
标题将显示文件的内容,而不是下载文件。感谢您提供的Olaf。但正如我前面所述,同一个php类在后端可以完美工作。我的CMS同时具有前端和后端,并且同一个脚本同时处理文件下载。有趣的是,下载的文件是gins在将编码更改为ANSI后工作
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;
}
Content-Disposition: attachment; filename="fname.ext"