您在这里遇到的问题实际上与(我猜)您正在使用session的事实有关。这可能有点牵强,但它会完全解释你所描述的。
这实际上不是“预期行为”,除非您的 Web 服务器设置为使用单个线程运行单个进程,我对此表示高度怀疑。这会造成网络服务器在任何时候只能处理一个请求的情况,这会影响网络上的每个人。这正是为什么您的 Web 服务器可能不会这样设置的原因——事实上,我怀疑您会发现这样配置您的服务器是不可能的,因为它会使服务器有些无用。在一些聪明的 alec 插话“Node.js 怎么样?”之前 - 这是一个特例,我相信你已经很清楚了。
当 PHP 脚本打开会话时,它会对存储会话数据的文件具有排他锁。这意味着任何后续请求都将在调用时阻塞,session_start()
而 PHP 尝试获取会话数据文件上的排他锁 - 它不能,因为您之前的请求仍然有一个。一旦您的上一个请求完成,它就会释放对文件的锁定,并且下一个请求能够完成。由于会话是每台机器的(实际上是每浏览会话,顾名思义,这就是它在不同浏览器中工作的原因),这不会影响您网络的其他用户,但会保留您的站点设置,以便这是一个即使对您而言,问题也是不好的做法,很容易避免。
解决方案是在session_write_close()
您完成给定脚本中的会话数据后立即调用。这会导致脚本关闭会话文件并释放它的锁定。您应该尝试在开始长时间运行的过程之前完成会话数据,或者在完成之前不要调用session_start()
。
从理论上讲,您可以稍后在脚本中调用session_write_close()
然后session_start()
再次调用,但我发现 PHP 有时在这方面表现出错误行为(我认为这与 cookie 有关,但不要引用我的话)。显然,请注意设置 cookie 会修改标头,因此您必须session_start()
在输出任何数据或启用输出缓冲之前调用。
例如,考虑这个脚本:
<?php
session_start();
if (!isset($_SESSION['someval'])) {
$_SESSION['someval'] = 1;
} else {
$_SESSION['someval']++;
}
echo "someval is {$_SESSION['someval']}";
sleep(10);
使用上述脚本,您必须等待 10 秒才能发出第二个请求。session_write_close()
但是,如果您在该行之后添加一个调用echo
,您将能够在前一个请求完成之前发出另一个请求。