是.
如果您正确使用HTTP标头,则无需任何异步处理即可轻松完成此操作.
在正常情况下,只要另一端的客户端关闭连接,PHP就会停止处理.如果你想在这个事件之后继续处理,你需要做一件事:告诉PHP忽略用户中止.怎么样?
ignore_user_abort()
这将允许您的脚本即使在客户端躲闪后也能继续运行.但我们也面临着如何告诉客户他们所做的请求已完成以便关闭连接的问题.通常,如果我们不指定它们,PHP会透明地处理为我们发送这些标头.但是,我们需要明确地执行此操作,否则客户端将不知道我们何时希望它们停止读取响应.
为此,我们必须发送适当的HTTP标头以告知客户端何时关闭:
Connection: close
Content-Length: 42
这种标头组合告诉客户端,一旦它读取42字节的实体主体响应,消息就完成了,并且它们应该关闭连接.这种方法有几个后果:
>您必须在发送任何输出之前生成响应,因为您必须确定其内容长度大小(以字节为单位),以便您可以发送正确的标头.
>在回显任何输出之前,您必须实际发送这些标题.
所以你的脚本看起来像这样:
ignore_user_abort();
// do work to determine the response you want to send ($responseBody)
$contentLength = strlen($responseBody);
header('Connection: close');
header("Content-Length: $contentLength");
flush();
echo $responseBody;
// --- client will now disconnect and you can continue processing here ---
使用此方法的大“Gotchya”是,当您在Web SAPI中运行PHP时,如果在最终用户客户端关闭连接后执行耗时的处理,则可以轻松地针对最大时间限制指令运行.如果这是一个问题,您可能需要考虑使用cron的异步处理选项,因为PHP在CLI环境中运行时没有时间限制.或者,您可以使用set_time_limitdocs在Web环境中提高脚本的时间限制.
值得一提的是,如果您执行此类操作,您可能还需要在生成响应主体时向connection_aborted()docs添加检查,以便在完成传输之前用户中止时可以避免其他处理.