繁体   English   中英

如何修复损坏文件的 PHP 下载脚本?

[英]How do I fix this PHP download script, which is corrupting files?

我有一个强制下载脚本,它可以使用 PDF 和纯文本产生良好的结果,并且使用 ZIP 存档(它们在 Windows 中工作,而不是在 Linux 中工作)。 但是,应用程序文件和图像都失败了。 这些构成了我必须处理的绝大多数文件。 正如我在这里看到的类似主题所建议的那样,压缩所有下载不是一种选择。

失败的文件下载到完整大小,并以正确的名称写入磁盘。 尝试打开它们会导致错误消息,该消息因类型而异。 将下载的文件与hexdump中的原始文件进行比较,我可以看到脚本在每个下载文件的开头插入以下字符:

ef bb bf

然后,下载的文件会复制原始文件,直到它停止在其指定的大小 - 所以原始文件的最后 6 个字符总是丢失。

不幸的是,我对二进制文件是如何构成的、这些字符可能意味着什么或脚本如何/为什么插入它们一无所知。

这是原样的脚本:

$file = '94.ppt';
$path = $_SERVER['DOCUMENT_ROOT']."/relative/path/";
$full_path = $path.$file;
if ($fd = fopen ($full_path, "r")) {
    $fsize = filesize($full_path);
    $path_parts = pathinfo($full_path);
    $ext = strtolower($path_parts["extension"]);
    switch ($ext) {
        case "pdf":
            header("Content-type: application/pdf");
            header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
        break;
        case "txt":
            header("Content-type: text/plain");
            header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
        break;
        case "jpg":
            header("Content-type: image/jpeg");
            header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
        break;
        case "ppt":
            header("Content-Type: application/vnd.ms-powerpoint");
            header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
        break;
        default;
            header("Content-type: application/octet-stream");
            header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
    }
    header("Content-Transfer-Encoding: binary");
    header("Content-length: $fsize");
    header("Cache-control: private");
    while(!feof($fd)) {
        $buffer = fread($fd, 2048);
        echo $buffer;
    }
}
fclose ($fd);
exit;

开发系统是 Apache 2.2.14 (Ubuntu) 上的 PHP 5.3.2-1。 生产主机是 Apache 2.0.63(某种类型的 Linux)上的 PHP 5.2.9。

EF BB BF是标准的 UTF-8字节顺序标记 有人 报告说,当您包含在脚本中的某些 PHP 文件是 UTF-8 编码时,就会发生这种情况; PHP 的某些版本通过发送 UTF-8 字节顺序标记来对此做出反应。 上面的链接建议在脚本开头调用ob_start()并在开始推出文件内容之前调用ob_end_clean() - 这样字节顺序标记就会被捕获在 output 缓冲区中。

此外,您可以简单地使用fpassthru到 pipe 您的文件到 output 而不是在循环中读写。

您的 PHP 脚本文件似乎以UTF-8 编码,BOM位于文件开头<?php分隔符之前的开头。 这些字节在您的实际 output 之前发送,从而损坏您的数据。

您只需要删除它并将您的编辑器配置为不使用 UTF-8 的 BOM。

EF BB BF是 UTF-8 编码字节顺序标记(BOM)。 我怀疑有一些配置选项可以关闭 BOM。

编辑:文件编辑器应该允许您在以相关字符编码(例如 UTF-8)保存文件时关闭 BOM。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM