我的网站上存在一个问题,当我使用PHP将Content-Disposition设置为“attachment”然后使用readfile()
发送文件时,我的文件下载被截断了。我知道这是一个臭名昭着的问题,因为在PHP的readfile()
手册页上有很多关于它的讨论。我已经尝试了在那里发布的每个解决方案都没有运气(发送分块输出,在Apache / PHP中禁用gzip压缩)。以下是该代码的要点,没有所有的解决方法,就像您在PHP手册中找到它一样:
$file = '/path/to/ugly.file.name.mp4';
$filename = 'ANiceFileName.mp4';
header('Content-Description: File Transfer');
header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename='.$filename.'.mp4');
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));
ob_clean();
flush();
readfile($file);
最重要的是,请注意我希望能够向浏览器发送动态文件名,以避免使用更加机器友好的代码将文件存储在磁盘上。是的,在这段代码执行之前我已经做了很多安全检查 - 我已经知道readfile()
可能是一个安全漏洞。 : - )
我发现发送完整文件的唯一可靠方法是简单地删除PHP,而是使用Apache的mod_header
来强制下载文件。像这样:
<FilesMatch "\.mp4$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
这非常有效,但是有一个大问题 - 我无法再根据请求生成动态文件名,这对我的内容有点重要。我已经知道如何指定;filename=file_name.mp4
,但请记住 - 我需要指定一个动态名称,而不仅仅是file_name.mp4
。
如果我能在发送文件时以某种方式通知Apache(使用PHP)动态文件名,那将是非常好的。那可能吗?或者我将被迫将磁盘上的所有文件重命名为用户友好名称? PHP解决方案根本不起作用。我的文件有时高达15MB,传输时通常会被截断为小于2MB。哎哟!
帮我Stack Overflow Kenobi!你是我唯一的希望。
答案 0 :(得分:0)
是否因为php脚本超时而被截断?参数或者set_time_limit?
答案 1 :(得分:0)
按照here所述尝试mod_xsendfile。这基本上允许PHP在PHP设置X-Sendfile标头时跳出HTTP对话的中间位置 - 但是,正如您在该博客上看到的那样,它允许设置Content-Disposition标头。