使用Content-Disposition的Apache mod_header和文件下载的动态文件名

时间:2011-02-24 08:37:28

标签: php apache dynamic

我的网站上存在一个问题,当我使用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!你是我唯一的希望。

2 个答案:

答案 0 :(得分:0)

是否因为php脚本超时而被截断?参数或者set_time_limit?

答案 1 :(得分:0)

按照here所述尝试mod_xsendfile。这基本上允许PHP在PHP设置X-Sendfile标头时跳出HTTP对话的中间位置 - 但是,正如您在该博客上看到的那样,它允许设置Content-Disposition标头。