【问题标题】:PHP – Sending quick API response to client while server worksPHP – 在服务器工作时向客户端发送快速 API 响应
【发布时间】:2011-03-26 14:01:15
【问题描述】:

我创建了一个在多个站点上使用的 API。客户端站点使用 file_get_contents 或 curl 调用服务器并访问我们的 URL,例如“http://www.myserver.com/api/record.php?some=thing”。客户端进行调用,然后等待 API 响应,然后再处理页面的其余部分。但是,有时客户端不需要 API 的输出。

我想知道是否有办法让服务器输出一些东西,这样客户端就不会在服务器进程执行它需要做的事情时等待它。类似于“页面完成”的内容,因此客户端不再等待它加载,但服务器脚本在插入数据库条目时仍在运行一秒钟。

我了解到进程控制功能仅供 CLI 使用,不应在 Web 服务器环境中使用,因此生成新进程是不可能的。

有什么建议吗?我知道使用 javascript 进行异步调用是可行的,但我们发现 PHP 访问必须比 JS 更可靠。

非常感谢!

【问题讨论】:

  • 在关于异步调用的最后一段中,您指的是作为客户端访问 API 对吗?

标签: php web-services api rest http-headers


【解决方案1】:

你可以这样做:

ob_start();

//create and output any output to be sent to the browser.

// get the size of the output
$size = ob_get_length();

// send headers to tell the browser to close the connection
header("Content-Length: $size");
header('Connection: close');

// flush all output
ob_end_flush();
ob_flush();
flush();

//do any post-processing here.

【讨论】:

  • 快速测试表明,基于这些行,浏览器和 apache 都不会关闭连接并停止加载,直到脚本完成,所以大概 curl 和 file_get_contents 也会等到连接实际关闭.
  • ps。否决票不是我的,我认为这个想法可以/应该能够奏效。
  • 这是我的。 Connection: close 仅告诉客户端在发送请求正文后关闭连接(另一种选择是保持连接状态,以防客户端想要发送另一个请求时保持连接打开)。
  • 我可以发誓这行得通(由于明确的 content-length 标头),但你是对的,它没有。
  • 该死,我一直在寻找这样的简单解决方案。我要试试其他的,过几天再来报告。感谢大家的意见!
【解决方案2】:

编辑:再想一想,发出异步请求根本没有任何好处。只需使用fsockopen 发出正常请求,并在fwrite 标头完成后将其终止。

您可以只发出一个 HEAD 请求来表示您不想要响应的正文 - 这将节省一些行程。

原则上,您可以创建一个async request。编写标题后,您必须确保它们已正确发送。此时,您可以中止连接并依赖ignore_user_abort 服务器端。 (不过,我不确定这是否适用于所有网络服务器,在这么早的用户中止之后,请求可能永远不会到达 PHP)。

【讨论】:

    【解决方案3】:

    脚本和 api 之间的连接是一件棘手的事情;您必须终止它以使 curl 或 file_get_contents 返回。 (您可以查看异步 curl_multi_* 函数或像 artefacto 建议的那样进行自己的套接字处理)

    一种选择是将后端处理置于后台进程中,如下所示:

    $desc = array(); // fd descriptors
    $proc = proc_open("/bin/sleep 60 &",$desc,$pipes);
    

    睡眠只是为了证明概念。连接完成后,它继续快乐地生活。不利的一面是,如果您连接了任何 fd,子进程将与父进程一起死亡,因此您必须通过命令行或 $env (5th arg to proc_open) 将数据推入

    【讨论】:

    • 虽然这不是我使用的解决方案,但它是最好的方法。您必须快速返回并关闭连接,但在此之前,要么在后台启动一个进程,要么将其排队等待其他进程运行。
    猜你喜欢
    • 1970-01-01
    • 2018-08-01
    • 2021-04-27
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多