是否可以关闭PHP脚本的输出流?我有一个脚本需要做一些后期处理,但在后期处理期间和之后它不再向客户端发送任何数据,所以我想在后期处理之前关闭连接。
编辑:在我的应用程序中,我有一个需要不时重建的缓存。但是,我不想让用户放慢速度。我想要的是在脚本的最后确定是否需要重建缓存。所以我想首先关闭输出流,以便用户获取它的数据,然后我想重建缓存。这样做并不是非常关键,但我认为最好先关闭连接,这样用户就不会注意到缓存正在重建,如果这需要很长时间。
答案 0 :(得分:5)
<强>更新强>
处理这种情况的方法是输出缓冲和适当的HTTP标头的组合。
来自HTTP/1.1 Specification Section 14.10:
HTTP / 1.1为发件人定义“关闭”连接选项 表示连接完成后将关闭 响应。
因此,除了 Connection:close 之外,如果我们传递HTTP Content-Length 标头,浏览器知道在收到指定的响应长度后关闭连接:
另外,请注意,如果进行过多处理,可以在Web服务器SAPI中遇到脚本执行时间限制。最后,您应该告诉PHP使用ignore_user_abort()
忽略此特定脚本中的“用户中止”,因为浏览器将因您正在执行的操作而关闭连接,并且您希望PHP继续处理。
<?php
ignore_user_abort();
ob_start();
// do stuff, generate output
// get size of the content
$length = ob_get_length();
// tell client to close the connection after $length bytes received
header('Connection: close');
header("Content-Length: $length");
// flush all output
ob_end_flush();
ob_flush();
flush();
// close session if you have one ...
// continue your processing tasks ...
?>
您可以查看Connection handlingdocs上的PHP手册部分。
或者,为什么不开始输出缓冲?然后,您可以捕获将要发送的所有输出,然后在您确实想要对其执行任何操作时稍后决定。
<?php
echo 'before output buffering';
ob_start();
echo 'after output buffering';
$output = ob_get_contents();
// script's only output to this point will be 'before output buffering'
// I changed my mind, send the output ...
ob_end_flush();
?>
答案 1 :(得分:0)
fclose(STDOUT)
:http://php.net/manual/en/features.commandline.io-streams.php
答案 2 :(得分:0)
我没有足够的声誉来发表评论,但我想在@rdlowrey回答中分享 gzip 可能是个问题。
如果您启用了 gzip ,则传输编码标头始终设置为 chunked ,即使您尝试使用{{ 1}}因此它不会发送 Content-Length 标题。
我能解决这个问题的方法是使用下一个:
header("Transfer-encoding: none");
然后是解决方案:
<?
@ini_set('zlib.output_compression', 'Off');
@ini_set('output_buffering', 'Off');
@ini_set('output_handler', '');
@apache_setenv('no-gzip', 1);
?>