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


PHP background Script blocking connection for whole browser

我有以下问题:

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

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

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

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

原因是什么?是否有每个浏览器打开的mysql连接的限制(每个会话,也就是说…)-我找不到任何关于这个…还是浏览器(尽管FireBug说连接已经终止)仍然在等待脚本的响应?

我该如何解决这个问题?谢谢你的帮助。

PHP脚本不能关闭client<->服务器连接,除非退出。执行Connection: close标头也不做任何事情,因为这是客户端->服务器请求,并且无论如何都是默认操作,除非客户端特别请求Connection: keep-alive

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

如果您想在等待此邮件脚本处理时继续能够使用FF,那么在进入邮件发送器循环之前发出session_write_close()。这将关闭并解锁会话文件,并允许您在FF的另一个选项卡中继续使用该站点。

如果你想让这个脚本真正独立于浏览器,那么它必须把自己pcntl_fork放到后台。这个分叉的子进程可以处理这个过程,完全不依附于浏览器,并且原始脚本可以退出,允许连接关闭。