【发布时间】:2010-03-16 21:06:01
【问题描述】:
首先:我是一个卑微的网页设计师,他知道的 PHP 是危险的,而且对服务器管理的了解也足够了,好吧,什么都不是。除非你很清楚,否则我可能不会理解你!
设置:我已经建立了一个网站,客户端将文件上传到特定目录,这些文件通过 php 可供用户下载。这些文件通常是超过 50MB 的可执行文件。客户不希望它们被压缩,因为他们觉得他们的用户不够精明,无法解压缩它们。我正在使用下面的 php 来强制下载对话框并隐藏文件所在的目录。
它是 Linux 服务器,如果有区别的话。
问题:用户尝试下载某个文件后,该文件已损坏。它是一个可执行文件,但是当单击它时,会打开一个空白的 DOS 窗口。下载前的原始文件可以完美打开。还有其他几个类似的文件经过相同的下载过程,所有这些都可以正常工作。
我尝试过的事情:我尝试上传压缩文件,然后在服务器上解压缩以确保它在上传过程中没有损坏,但没有运气。我也试过将原始文件的二进制代码与下载的不起作用的文件进行比较,它们完全相同(因此 php 不会意外地在文件中插入任何额外内容)。
可能是我的 downloadFile 函数中的标头有问题吗?我真的不知道如何解决这个问题......
这是下载的 php,如果相关的话($filenamereplace 在别处定义):
downloadFile("../DIRECTORY/files/$filenamereplace","$filenamereplace");
function downloadFile($file,$filename){
if(file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
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));
@ flush();
readfile($file);
exit;
}
}
ETA 附加信息: - 工作/非工作文件的测试已在同一台机器上完成 - 如果有任何不同,原始文件有一个自定义图标。下载后,该文件有一个通用的空白文档图标。
附加信息:我认为这很重要! 我只是尝试直接下载文件(绕过上面触发下载功能的下载链接)。如果我只是通过访问其 url 并以这种方式下载文件来下载文件,则下载的文件可以工作。所以我认为它必须与下载功能有关。但是什么??
3/17 重大更正——并已解决—— 所以我今天早上醒来,突然意识到我可能是在比较文件错误。 (我已将它们重新保存为二进制文本,然后比较了它们。我没有意识到比较程序会比较实际的 exe 文件)。今天早上我试着比较了实际的 exe 文件,发现有 不同。有一行 php 代码被注入到文件的第一行。我调整了php,问题就解决了。 (它来自 if/else 语句,它在我引用的代码中定义了 $filenamereplace 变量)。再次感谢您的所有帮助,并很抱歉误导您坚持认为文件内容相同!
【问题讨论】:
-
我认为您不必刷新标题。一些十六进制编辑器可以比较文件
-
我应该删除那个“@flush();”吗?那么线呢?标题的冲洗可能是导致问题的原因,还是您只是说没有必要。 (老实说,我不知道它实际上做了什么……)
-
一点澄清 - 您可以在下载版本失败的同一台机器上打开原始文件(预上传)吗?只是为了确保删除任何机器特定的问题?如果位相同并且其他 exe 下载正常,在我看来您需要开始查看环境(例如机器)配置问题吗?
-
埃里克,好问题。是的。原文件会完美打开,当我从同一台机器上的服务器下载文件时,下载的文件打不开。
-
另外,我不知道这是否有区别,因为我习惯在 Mac 平台上工作,但我注意到,虽然文件名为“file.exe”,但下载的文件,正如它在桌面上显示的那样,仅称为“文件”。隐藏文件扩展名是否正常?我实际上尝试在下载后将.exe添加回文件名,只是为了试一试,但没有任何区别。
标签: php file-upload download