gpt4 book ai didi

php - 如何在服务器中运行 PHP 代码的同时阻止 PHP 向客户端发送数据?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:55:09 25 4
gpt4 key购买 nike

当我遇到一个导致我的 PHP 程序无限循环的错误时,我想到了这个问题。这是一个示例情况:

假设我有一个接收图片上传的 PHP 网页(该页面可能是图片上传表单的响应页面)。在服务器中,脚本应该将图像存储在一个临时文件中。然后脚本应该向客户端输出一条确认消息,然后停止发送数据,这样客户端就不会等待。然后脚本应继续执行,在结束前处理图像(如调整图像大小)。

我认为这种“技术”可能很有用,这样客户端就不会在耗时的过程中等待,从而防止超时。

另外,这个问题可以使用 HTTP 方法解决吗?

最佳答案

是的。

如果您正确使用 HTTP header ,无需任何异步处理即可轻松完成此操作。

在正常情况下,只要另一端的客户端关闭连接,PHP 就会停止处理。如果你想在这个事件之后继续处理,你需要做一件事:告诉 PHP 忽略用户中止。怎么办?

ignore_user_abort()

这将使您的脚本即使在客户端摆脱闪避之后也能继续运行。但是我们也面临着如何告诉客户端他们发出的请求已经完成以便关闭连接的问题。通常,如果我们不指定它们,PHP 会透明地为我们处理发送这些 header 。不过,在这里,我们需要明确地执行此操作,否则客户端将不知道我们希望他们何时停止阅读响应。

为此,我们必须发送适当的 HTTP header 以告知客户端何时关闭:

Connection: close
Content-Length: 42

这种 header 组合告诉客户端,一旦它读取了 42 字节的实体主体响应,消息就完成了,他们应该关闭连接。这种方法有几个后果:

  1. 您必须发送任何输出之前生成您的响应,因为您必须确定其内容长度(以字节为单位),以便您可以发送正确的 header 。
  2. 您必须在回显任何输出之前实际发送这些 header 。

所以你的脚本可能看起来像这样:

<?php

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 ---

此方法的最大“难点”在于,当您在 Web SAPI 中运行 PHP 时,如果您在最终用户客户端关闭连接后进行耗时处理,则很容易遇到最大时间限制指令。如果这是一个问题,您可能需要考虑使用 cron 的异步处理选项,因为 PHP 在 CLI 环境中运行时没有时间限制。或者,您可以使用 set_time_limitdocs 来提高 Web 环境中脚本的时间限制。 .

值得一提的是,如果你做这样的事情,你可能还想添加一个检查 connection_aborted()docs在生成响应正文时,如果用户在完成传输之前中止,您可以避免额外的处理。

关于php - 如何在服务器中运行 PHP 代码的同时阻止 PHP 向客户端发送数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12104311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com