PHP后台脚本阻止整个浏览器的连接

时间:2011-10-14 17:17:18

标签: php ajax background connection phpmailer

我有以下问题:

通过Ajax调用PHP脚本。脚本本身使用以下行关闭连接

ignore_user_abort(true);
header("Content-Length: 0");
header("Connection: close");
flush();

然后开始使用phpMailer在后台发送一堆邮件(在循环中并在每封邮件后使用sleep(1) - 将来我希望这是5个发送邮件后的随机秒数)。使用FireBug,我可以看到与脚本的连接直接终止。邮件也被发送。

但是,当脚本在后台运行时,我无法打开任何页面 - 它们会一直加载,直到后台脚本显然已经完成。奇怪的是:脚本似乎没有阻止整个服务器,因为连接限制仅适用于启动后台脚本的浏览器。因此,在我启动脚本后 - 比方说 - FireFox,我仍然可以访问Chrome中服务器上的页面。

可能是什么原因?每个浏览器是否有开放MYSQLi连接的限制(每个会话,就是......) - 我找不到任何内容......或者是浏览器(尽管FireBug说连接已经终止)但仍在等待对于剧本的回应?

我怎么能解决这个问题? 提前感谢您的帮助。

1 个答案:

答案 0 :(得分:6)

除了退出之外,PHP脚本无法关闭客户端< - >服务器连接。执行Connection: close标头也不会执行任何操作,因为客户端>服务器请求也是如此,并且无论如何都是默认操作,除非客户明确请求Connection: keep-alive

您看到的“在其他浏览器中工作”行为通常是由于PHP在请求处于活动状态时锁定会话文件。不同的浏览器不会共享cookie,因此每个浏览器都有自己的OWN独立会话。因此,虽然Firefox与此后台请求捆绑在一起,但Chrome正在使用的会话完全不受影响。

如果您希望在等待此邮件脚本处理时继续使用FF,请在进入邮件程序循环之前发出session_write_close()。这将关闭并解锁会话文件,并让您继续在FF的另一个选项卡中使用该站点。

如果您希望此脚本真正独立于浏览器,则必须将pcntl_fork本身放入后台。这个分叉的子进程可以处理完全未附加到浏览器的处理,原始脚本可以退出,允许连接关闭。