php - 文件下载已损坏

标签 php

我是一名实验室讲师,我试图通过将文件保存在 webroot 之上并强制他们登录(通过大学的 LDAP 进行身份验证)来确保我的学生无法提前下载他们的入门文件,验证它是超过发布时间然后使用 readfile 向他们发送文件。不幸的是,我发送的所有文件最终都已损坏。

我的代码是:

if (file_exists($path)) {
     //header('Content-Description: File Transfer');
     header('Content-Type: application/octet-stream');
     header('Content-Disposition: attachment; filename='.basename($path));
     //header('Content-Transfer-Encoding: binary');
     header('Expires:' . date('r', 0));
     header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
     //header('Pragma: public');
     header('Content-Length: ' . filesize($path));
     //ob_clean();
     //flush();
     readfile($path);
     exit(0);
 }

我什至尝试只发送纯文本,但也没有正确传输,最后以乱码告终。


编辑:

抱歉,我没有详细说明我已经尝试过的内容。我确实尝试发送一个简单的文本文件(尝试在记事本中检查 pdf 以查找 PHP 警告有点过分)。

我发送了一个只有内容的文件 This is plain text 结果是纯粹的乱码。主要是不可打印的字符。 1f 8b 08 00 00 00 00 00 00 03 0b c9 c8 2c 56 00 a2 82 9c 00


更新:

在其中一台服务器上禁用 gzip 压缩,文件仍然损坏。删除了 ob_clean(); flush() 和文本文件开始干净地通过(无法相信您在互联网上阅读的内容 :/)。

Zip 文件仍然损坏,但我的 PDF 现在可以读取了。再看一看,似乎在文件的开头添加了一个额外的换行符。回顾文本文件,它的前面确实有一个额外的换行符,最后一个字符丢失了。正如预期的那样,将 +1 添加到 Content-Length header 可以让最后一个字符通过,仍然在寻找前置换行符的来源。另外,如果我注释掉 readfile,我会得到一个只有 CRLF (0d0a) 的文件。

框架通常使用 View 和布局“包装”来自 Controller 的内容,但两者都设置为空白文件,并且头 Controller 正在检查它们是否为空白,然后跳过该行以回显生成的 HTML。即使这样,exit(0) 也应该确保只有析构函数在传输后被调用。我通过在布局和 View 中放置 echo 语句并相应地增加内容大小来验证这一点,并且该文本不会在下载的文件中结束,所以我相对确定换行符不是来自那里。

最佳答案

确保 PHP 脚本不包含 <?php ?> 之外的空行标签。一般来说,确保没有其他内容被回显,但文件。

如果您在这里发布结果文件内容,那将会非常有帮助。尝试使用简单的单行文本 文件。

关于php - 文件下载已损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12355891/

相关文章:

php - 如何创建与前一个表格具有相同尺寸的表格

php - 使用 WinSSL、NTLM、HTTP2、SSH2 和 IPv6 支持构建工作 libcurl

php - 在 PHP 中从 CSV 创建多维关联数组

php - 格式化 REPLACE 查询的注释日期

php - 我如何像我的 register.php 一样连接我的 login.php?

php - PHP在另一页上显示错误

php - 使用 PHP 的 Facebook 封面照片 API

php - Mysql多个where与post数据php

php - 用户下载文件后如何显示感谢页面?

php - 如何将自定义行为添加到 symfony 缓存 :clear?