【发布时间】:2011-08-01 17:18:59
【问题描述】:
最终更新
似乎我确实犯了一个非常简单的错误。因为我已经有一个流实现,所以我不能开始从流中读取:D
我正在尝试在 PHP 中实现类似 即发即弃 的功能。
<?php
ignore_user_abort(true);
header("Content-Length: 4");
header("Connection: Close");
echo "abcd";
flush();
sleep(5);
echo "Text user should not see"; // because it should have terminated
?>
如果我使用浏览器打开脚本,这将有效。 (显示“abcd”)。
但如果我用file_get_contents 或一些 stream 库打开它,它会等待约 5 秒并显示第二个文本。
我正在使用 PHP 5.2.11 / Apache 2.0
更新
我似乎对我要完成的工作有些困惑。
我不想使用输出缓冲区隐藏输出(这很愚蠢)。我想让客户端在服务器启动一个可能很长的过程(sleep(5))之前终止,我不希望客户端等待它(这就是即发即弃的意思,排序)。
使用输出缓冲区只是一个副作用。我在不使用输出缓冲区的情况下修改了示例代码。
我不明白的是:为什么这个脚本在从浏览器访问它与在 PHP 中使用 file_get_contents("http://dev/test.php") 或一些 stream 库获取它时表现不同?我在测试中看到的是,例如 stream_get_contents 在返回任何输出之前实际上会阻塞 5 秒,这与我想要的完全相反。
更新2
更多结果:
- 浏览器以某种方式响应
flush()。我不知道如何在 PHP 中使用 streams 复制这种行为,我的流一直阻塞。 - 我试过
fread,发现它的行为类似于stream_get_contents。 - 指定
maxlength无效,它仍会阻塞约 5 秒。 - 更改阻塞模式没有任何效果(除了产生更多调用
to stream_get_contents())。它会等待大约 5 秒,然后返回任何内容。 -
stream_set_read_buffer无效(在 PHP 5.3.5 服务器上测试)
【问题讨论】:
-
你想达到什么目的?如果您不想将最后的文本发送给客户端,为什么要将其输出给客户端?
-
我认为你不应该使用
ob_end_clean()和ob_end_flush。选择一个。 -
@hakre 文本的打印就是一个例子。我真正想做的是开始一些过程,我不想让客户等待它。我认为“一劳永逸”将是一个众所周知的术语。
-
@hugo_leonardo,我已修改示例代码以不使用输出缓冲区。
标签: php stream fire-and-forget