我正在尝试解决从php脚本下载“zip”文件时遇到的问题。似乎当我使用以下代码下载文件时,下载的文件在文件的开头附加了额外的0A09,导致winzip抛出损坏错误。
<?php
$pagePermissions = 7;
require_once ('util/check.php');
require_once ('util/file_manager.php');
$file_manager = new FileManager();
if ($_SERVER['REQUEST_METHOD'] == "GET") {
if (isset($_GET['q']) && $_GET['q'] == 'logout') {
//require_once ('util/users.php');
//$userdata = new Userdata();
$userdata -> kill_session();
header("Location: download.php");
exit ;
}
if (isset($_GET['q']) && $_GET['q'] == 'fetch') {
if (isset($_GET['name'])) {
@apache_setenv('no-gzip', 1);
header("Content-length: " . filesize('upload/' . $_GET['name']));
header('Content-type: application/zip');
//header("Content-Disposition: attachment; filename=\"{$_GET['name']}\" ");
header("Content-Disposition: attachment; filename={$_GET['name']}");
header('Content-Transfer-Encoding: binary');
readfile('upload/' . $_GET['name']);
exit();
}
}
}
?>
任何帮助都将非常感激,文件通过直接链接下载正常,文件开头附加的2个字节仅通过此代码发生。 提前致谢
答案 0 :(得分:22)
删除最后一个?>
并检查您的开始标记是否位于脚本的第一个字符的第一行。 PHP文件不必须以结束标记结束。您下载的文件包含(或更多)\r\n
的原因是因为PHP将直接回显(输出)<?php ?>
之外的任何内容。通常,如果你的脚本没有回显HTML,你将省略关闭的PHP标记,因为它不是强制性的,IMO会产生比其他任何东西更多的麻烦。
** 修改 **
如果您阅读了readfile
的PHP手册,那么您有一个有用的示例,几乎是您在问题中的代码,少了两行代码:
@apache_setenv('no-gzip', 1);
header("Content-length: " . filesize('upload/' . $_GET['name']));
header('Content-type: application/zip');
//header("Content-Disposition: attachment; filename=\"{$_GET['name']}\" ");
header("Content-Disposition: attachment; filename={$_GET['name']}");
header('Content-Transfer-Encoding: binary');
// add these two lines
ob_clean(); // discard any data in the output buffer (if possible)
flush(); // flush headers (if possible)
readfile('upload/' . $_GET['name']);
exit();
如果之后仍有问题,那么问题可能与您的PHP代码无关。
答案 1 :(得分:1)
很抱歉迟到的回复.....
我不知道我是对的,直到你投了这个......
将您的代码编辑为:
ob_start("");
//instead of ob_start(); with out a null callback
和
ob_end_clean(); //at the end , Note : "important" add instead of ob_end_flush()
即;
ob_start("");
//header
ob_end_clean();
答案 2 :(得分:0)
我今天遇到了与readfile()相关的类似问题。事实证明我的php.ini文件已启用输出压缩,并且正在弄乱试图检索文件的闪存模块。 (我想它无法处理它。)
我所要做的只是关闭php.ini文件中的压缩:
zlib.output_compression = off
或者,在您的脚本中:
<?php ini_set('zlib.output_compression', 'Off'); ?>
只是想分享一下,以防其他人在从readfile()输出接收文件时遇到问题。
答案 3 :(得分:0)
我在Joomla(2.5)中遇到了类似的问题,使用readfile将Excel(.xls)文件传回给用户。
我还注意到文本和xml文件也在开头插入了一些代码,但几乎忽略了它因为xml&amp;文本阅读器仍倾向于打开文件。
我决定尝试Yanick的建议(而不是使用服务器压缩选项),只需在readfile之前刷新缓冲区:
ob_clean(); // discard any data in the output buffer (if possible)
flush(); // flush headers (if possible)
嘿presto,它有效。我建议将此作为一个替代答案:突出根本原因,显示它可以修复Joomla问题,因为我有二进制和文本返回的混合。
添加(道歉,如果这很明显!) - mime类型设置工作正常:
$document = JFactory::getDocument();
$document->setMimeEncoding($mimetype);
当mime类型为application / octet-stream时,我甚至不需要设置'Content-Transfer-Encoding:binary'。
答案 4 :(得分:0)
我有同样的问题所以我使用了这个标题,我得到了我的解决方案。
$filename = ABSPATH.'/wp-content/summary/user_content/'.trim($file);
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Description: File Transfer');
header('Content-Type: text/text');
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: max-age=0');
readfile($filename);
exit;
答案 5 :(得分:0)
在图像文件开始处的空白处,我遇到了类似的问题。
我怀疑我的问题是由打开前的空白引起的
对我有用的是:
@ob_start(''); //@ supresses a warning
//header entries
ob_end_clean();
ob_clean();
readfile($file);