0

最终更新

好像我确实犯了一个非常简单的错误。由于我已经有一个流实现,我不能开始从流中读取:D


我正在尝试在 PHP中实现类似即发即弃的功能。

来自 php.net

<?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某个库打开它,它会等待约 5 秒并显示第二个文本。

我正在使用 PHP 5.2.11 / Apache 2.0


更新

我似乎对我要完成的工作有些困惑。

我不想使用输出缓冲区隐藏输出(这很愚蠢)。sleep(5)我想让客户端在服务器启动一个可能很长的进程(使用输出缓冲区只是一个副作用。我在不使用输出缓冲区的情况下修改了示例代码。

我不明白的是:为什么这个脚本在从浏览器访问它与在 PHP 中使用file_get_contents("http://dev/test.php")或某些库获取它时表现不同?我在测试中看到的是,例如stream_get_contents在返回任何输出之前实际上会阻塞 5 秒,这与我想要的完全相反。

更新2

更多结果:

  • 浏览器以某种方式响应flush(). 我不知道如何用PHP 中的复制这种行为,我的流一直阻塞。
  • 我试过fread了,发现它的行为类似于stream_get_contents.
  • 指定 amaxlength无效,它仍会阻塞约 5 秒。
  • 更改阻塞模式没有任何效果(除了产生更多的调用to stream_get_contents())。它会在返回任何东西之前等待约 5 秒。
  • stream_set_read_buffer没有效果(在 PHP 5.3.5 服务器上测试)
4

3 回答 3

0

文本的第二部分出现了,因为您正在使用ob_end_flush()and停止输出缓冲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()隐藏后保留所有内容。

于 2011-08-01T17:56:11.973 回答
0

如何使用 file_get_contents 访问脚本?您如何使用浏览器访问它?如果你在没有“http://”的情况下访问脚本,当然它永远不会被执行。使用与浏览器中相同的 URL。

编辑:

浏览器甚至会在连接关闭之前呈现页面。即使您冲洗,我也不认为连接已关闭。您可以启动 Wireshark 并检查。stream_get_contents 和 file_get_contents 将阻塞,直到它们有所有的输出。即使您冲洗,他们也无法确定没有更多内容。由于 content-length 标头似乎没有让 {file,stream}_get_contents 更早返回,因此您可能需要实现自己的缓冲,ala。fopen,读取,fclose。

于 2011-08-01T21:27:20.363 回答
0

好像我确实犯了一个非常简单的错误。由于我已经有一个流实现,我不能开始从流中读取:D

于 2011-08-02T15:41:11.613 回答