文件下载已损坏

时间:2012-09-10 16:34:49

标签: 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


更新

禁用其中一台服务器上的gzipping,文件仍然损坏。删除了ob_clean(); flush()并且文本文件开始干净利落(不能相信你在互联网上阅读的内容:/)。

Zip文件仍然损坏,但我的PDF现在可读。还有一些看起来似乎在文件的最开头添加了一个额外的换行符。回顾文本文件,它在前面有一个额外的换行符,并且缺少最后一个字符。正如预期的那样,将+1添加到Content-Length标头可以让最后一个角色通过,仍然可以查找前置换行符的来源。另外,如果我注释掉readfile,我会收到一个只包含CRLF(0d0a)的文件。

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

1 个答案:

答案 0 :(得分:1)

确保PHP脚本不包含<?php ?>个标记中的空行。通常,确保没有回显其他内容,但文件。

如果您在此处发布结果文件内容,那将非常有用。尝试使用简单的单行文本文件。