最终更新
好像我做了一个非常简单的错误。由于我已经有了一个流实现,因此我无法从流中读取:D
我正在尝试在PHP中实现 fire-and-forget 之类的功能。
<?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)
)之前终止,并且我不希望客户端等待它(这就是“即发即忘”的意思,排序)。
输出缓冲区的使用仅仅是副作用。我在不使用输出缓冲区的情况下修改了示例代码。
我不明白的是:为什么这个脚本在从浏览器访问时的行为与使用file_get_contents("http://dev/test.php")
或某些 stream 库在PHP中获取它时的行为不同?我在测试中看到的是,例如stream_get_contents
实际上会在它返回任何输出之前阻塞5秒,这与我想要的完全相反。
UPDATE2
更多结果:
flush()
。我无法弄清楚如何使用PHP中的 streams 复制此行为,我的流阻止。fread
,发现其行为与stream_get_contents
类似。maxlength
无效,它仍将阻止约5秒。to stream_get_contents()
)。在返回任何东西之前它会等待约5秒钟。stream_set_read_buffer
没有效果(在PHP 5.3.5服务器上测试)答案 0 :(得分:0)
第二部分文字正在显示,因为您正在使用ob_end_flush()
和ob_end_clean()
停止输出缓冲。当发生这种情况时,PHP会正常输出内容。尝试以下内容:
<?php
ob_start(); // turn on output buffering
print "Text the user will see.";
ob_flush(); // send above output to the user and keep output buffering on
print "Text the user will never see";
ob_end_clean(); // empty the buffer and turn off output buffering. your script should end here.
?>
ob_end_clean()
出现在脚本末尾非常重要。它会清空缓冲区并且不会将其内容发送给用户,从而保留隐藏ob_flush()
之后的所有内容。
答案 1 :(得分:0)
如何使用file_get_contents访问脚本?你如何使用浏览器访问它?如果您在没有“http://”的情况下访问脚本,当然它永远不会被执行。使用与浏览器中相同的URL。
编辑:
即使在连接关闭之前,浏览器也会呈现页面。即使你刷新,我也不认为连接是关闭的。你可以启动Wireshark并检查。 stream_get_contents和file_get_contents将阻塞,直到它们具有所有输出。即使你脸红了,也无法确定没有更多的内容。由于内容长度标题似乎没有使{file,stream} _get_contents更早返回,因此您可能需要实现自己的缓冲,ala。 fopen,read,fclose。
答案 2 :(得分:0)
好像我做了一个非常简单的错误。由于我已经有了一个流实现,因此我无法从流中读取:D