PHP同时从同一个浏览器和同一个PHP脚本下载多个文件。

3
<?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);
?>

你好, 我有一个简单的代码,可以强制下载随机文件。我的问题是,如果我从同一个浏览器中两次或更多次调用脚本,则第二次下载将不会开始,直到第一次下载完成或中断为止。因此,每次只能下载一个文件。 你有什么线索吗?

5个回答

6
这可能与PHP的会话处理有关。使用默认的会话处理程序时,当PHP脚本打开会话时,它会将其锁定。需要访问它的后续脚本必须等待第一个脚本完成并解锁它(在关闭时自动发生或通过session_write_close())。这将表现为脚本不执行任何操作,直到前一个脚本以完全相同的方式完成。
显然,您没有明确启动会话,但有一个配置标志会导致会话自动启动:session.auto_start - http://www.php.net/manual/en/session.configuration.php 要确定此设置是否设置为true,请使用phpinfo(),或查看配置文件。您还可以尝试在脚本顶部添加session_write_close(),看看是否可以解决问题。

通过搜索找到了这个旧答案,session_write_close(); 正是我所需要的。只需要确保在下载开始之前正确调用它即可。谢谢! - Greg W

3

我想说的是,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);
?>

我找到的第一个解决方案提到在文件流数据之前放置session_write_close()。 - ImaginedDesign

3

只是猜测,可能有不同的原因。

首先,您的服务器可能限制连接或并行的子进程数。但我猜这不是问题所在。

其次,更有可能的是客户端限制连接数。 "正常" 浏览器一次只打开两个连接到某个服务器。现代浏览器允许最多8个连接。这是为了避免与慢速服务器可能发生的问题而进行的简单限制。

一个解决方法是将每个下载放在“虚拟”子域上。

试试吧!


1

我会进一步调查Ralf关于服务器限制的建议,并从检查日志文件开始,以确保服务器是否收到了第二个请求。有了这些知识,您可以排除其中的一种可能性并至少看到问题所在的位置。

从客户端的浏览器 - 您没有提到是哪一个 - 如果是Firefox,请尝试安装 Live Http Headers扩展程序,以查看您发送的请求的情况以及浏览器是否从服务器端接收到任何响应。


0
就我所知,没有 PHP 配置设置限制最大下载次数或类似的限制 - 此外,这种配置超出了 PHP 的范围。
因此,我只能得出两个结论:
  • 第一个是这是浏览器的行为,查看该问题是否在多个浏览器中重复出现(如果是,请告诉我)。HTTP 规范确实说同一域名仅应有两个连接处于活动状态,但我不知道它是否会影响文件下载以及页面下载。解决这种限制的方法是将多个子域分配给同一站点(或执行捕获所有子域的 DNS 条目),并在生成下载链接时选择一个随机子域来下载。如果这是浏览器问题,这应该可以解决多个请求的问题。

  • 第二个选项更不太可能发生,只适用于使用 Apache 的情况下,您的 MaxKeepAliveRequests 配置选项设置为某个极低值,并启用了 KeepAlives。但是,我非常怀疑这是否是问题,因此建议调查浏览器的可能性。

当第二次下载开始时,您是否从浏览器收到错误消息,还是它只是挂起了?如果它只是挂起了,那么这表明这是一个浏览器问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接