<?php
$filename= './get/me/me_'.rand(1,100).'.zip';
header("Content-Length: " . filesize($filename));
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename=foo.zip');
readfile($filename);
?>
您好, 我有这个简单的代码强制随机文件下载,我的问题是如果我从同一个浏览器调用脚本两次或更多次,第二次下载将不会开始,直到第一次下载完成或中断。因此,我每次只能下载一个文件。 你有什么线索吗?
答案 0 :(得分:6)
这可能与PHP的会话处理有关。
使用默认会话处理程序,当PHP脚本打开会话时,它会锁定它。需要访问它的后续脚本必须等到第一个脚本完成它并解锁它(这在关机时自动发生,或者通过session_write_close())。这将表现为脚本没有做任何事情,直到前一个脚本以你描述的完全相同的方式完成。
显然,您没有明确启动会话,但是有一个配置标志会导致会话自动启动:session.auto_start - http://www.php.net/manual/en/session.configuration.php
使用phpinfo()确定是否设置为true,或查看配置。您也可以尝试将session_write_close()添加到脚本的顶部,看看它是否会使问题消失。
答案 1 :(得分:3)
首先,您的服务器可以限制并列中的连接数或子项数。但我想这不是问题
第二,客户端更有可能限制连接数。 “普通”浏览器一次只打开两个连接到某个服务器。现代浏览器允许最多8个(?)连接。这是一个简单的限制,以避免服务器速度慢的问题。
一种解决方法是将每个下载放在“虚拟”子域中。
试一试!
答案 2 :(得分:1)
我将进一步调查Ralf关于服务器限制的建议,并从检查日志文件开始,以确保服务器完全接收到第二个请求。拥有这些知识,您可以消除其中一种可能性,至少可以看出问题所在的一面。
从客户端的浏览器 - 您没有提到它是哪一个 - 如果是Firefox,请尝试安装Live Http Headers扩展名以查看请求发送的内容以及浏览器是否从服务器端收到任何响应。
答案 3 :(得分:1)
只是说session_write_close();
解决了我的问题。
我正在使用session_destroy();
(有效)但如果我需要保留会话数据则不太好:)
您需要做的只是在开始流式传输文件数据之前放置session_write_close();
。
示例:
<?php
$filename= './get/me/me_'.rand(1,100).'.zip';
session_write_close();
header("Content-Length: " . filesize($filename));
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename=foo.zip');
readfile($filename);
?>
答案 4 :(得分:0)
据我所知,没有php配置设置限制最大下载或类似的东西 - 此外,这样的配置超出了php的范围。
因此,我只能得出两个结论:
首先是这是浏览器行为,看看是否在多个浏览器中重复出现问题(如果有,请告诉我)。 HTTP规范确实说,同一个域中只有两个连接应该是活动的,但我不知道受影响的文件下载以及页面下载。解决此类限制的一种方法是将多个子域分配到同一站点(或执行全部子域DNS条目),并在生成下载链接时,选择要从中下载的随机子域。如果是浏览器问题,这应该解决多个请求问题。
第二个也是更不可能的选择是(这只适用于您使用Apache的情况),您的MaxKeepAliveRequests配置选项设置为低得离谱且启用了KeepAlive。但是,我非常怀疑这是问题,因此我建议调查浏览器的可能性。
您是在第二次下载启动时从浏览器收到错误消息,还是仅挂起?如果它只是挂起,这表明这是一个浏览器问题。