PHP控制输出

一: PHP header 函数

该函数发送原生 http 头。必须在任何实际输出之前调用,不管是普通的 html 标签,还是文件或PHP输出的空行、空格。

注意:header 函数之后的php代码仍然会被执行。

若是在 header 函数之前有内容输出,则产生如下警告:

Warning: Cannot modify header information - headers already sent by (output....)

// 示例一:
<html>asdf</html>
<?php
header('Location : http://segmentfault.com/');
// 示例二:
<?php
echo "html";
header('Location : http://segmentfault.com/');

但是,以上两个示例的代码并没有产生警告。原因是虽然使用了 html标签 或者 echo 输出函数,但是服务器会缓存内容,这些内容还没有作为 http 报文输出,这个时候仍有机会修改 HTTP 头。以下两个示例的代码会发出警告

// 示例三:
<?php
echo "<html></html>";
ob_flush();
flush();
header('Location: http://segmentfault.com/');
// 示例四:
<?php
for($i = 0; $i < 1e5; $i++) echo $i;
header('HTTP/1.1 200 OK');

二: PHP 控制输出 ob 函数

函数作用返回值
flush刷新输出缓冲,将当前为止程序的所有输出发送到用户浏览器void
ob_flush输出缓冲区中的内容,此函数不会销毁输出缓冲区void
ob_end_flush输出缓冲区内容并关闭缓冲true / false
ob_end_clean清空缓冲区并关闭缓冲true / false
ob_start打开输出控制缓冲true / false

查看以下示例:

// 示例一: 不会每隔1s输出 $i
<?php 
for ($i=10; $i>0; $i--) {
    echo $i;
    flush();
    sleep(1);
}
?>

// 示例二:添加 ob_end_clean() 或者 ob_end_flush() ,实现每隔1s输出$i
<?php
ob_end_clean();
for ($i=10; $i>0; $i--) {
    echo $i;
    flush();
    sleep(1);
}
?>

// 示例三:添加 ob_flush() ,也实现了每隔1s输出$i
<?php
for ($i=10; $i>0; $i--) {
    echo $i;
    ob_flush();
    flush();
    sleep(1);
}
?>

原因分析:php.ini 文件中 output_buffering = 4096;// 该设置的作用就是把输出缓冲一下,缓冲大小为4096bytes。

示例一中就是因为输出不够 4096bytes 或者脚本未执行结束 ,所以输出是不会发送出去的

示例二中 ob_end_clean 与 ob_end_flush 作用都是终止缓冲。这样就不用等到 4096bytes才发送输出内容了

示例三中 ob_flush 的作用是把缓冲的数据发送出去,但是不会终止缓冲。它必须每次在 flush 之前调用,因为它只是释放出了缓冲区中的内容,而 flush 是将不在缓冲区中的输出或者说释放出来的数据发送到客户端浏览器。

若是不想调用 flush 以及 ob_flush ,可以设置ini文件中 output_buffering=0,不能用ini_set 设置,因为在脚本一开始的时候缓冲设置就已经被载入了。其次还可以采用以下两种方式

// ob_implicit_flush — 打开/关闭绝对刷送
<?php
ob_implicit_flush(true);
for($i=0;$i<10;$i++) {
    echo $i;
    ob_flush();
    sleep(1);
}

// ob_end_clean 或者 ob_end_flush
<?php
ob_end_clean();
ob_implicit_flush(true);
for($i=0;$i<10;$i++) {
    echo $i;
    sleep(1);
}

ob_end_flush 与 ob_end_clean 的区别

// 多次打开、关闭缓冲区。注释掉一个ob_start后,最后一个ob_end_flush发出警告,类推
<?php
ob_start();
echo "A<br />";
ob_start();
echo "B<br />";
ob_start();
echo "C<br />";
ob_end_flush();
ob_end_flush();
ob_end_flush();
// 输出结果 A B C 

<?php
ob_start();
echo "A<br />";
ob_start();
echo "B<br />";
ob_start();
echo "C<br />";
ob_end_clean(); // 清空缓冲区并关闭
ob_end_flush();
ob_end_flush();
// 输出结果 A B

<?php
ob_start();
echo "A<br />";
ob_start();
echo "B<br />";
ob_start();
echo "C<br />";
ob_end_clean();
ob_end_flush();
ob_end_clean();
// 输出结果 什么也不输出

此处面临多级缓冲机制。程序中有三个 ob_start 意味着有三个缓存区 A、B、C,PHP程序本身还有一个最终输出缓冲区F。这些缓冲区的层次为 C > B > A > F,F层次最高,是程序最终的输出缓冲区。

刚开始 F:null ——> ob_start();// 新建缓冲区A:null ——> echo "A<br />" // 输出进入缓冲区A ——>  ob_start(); // 新建缓冲区B:null ——>  echo "B<br />" // 输出进入缓冲区B ——> ob_start();// 新建缓冲区C:null ——> echo "C<br />" // 输出进入缓冲区C

——> ob_end_clean() // 缓冲区C被清空并关闭 ——> ob_end_flush() // 缓冲区B输出到上一级缓冲A,并关闭 ——> ob_end_clean() // 清空缓冲A并关闭 ——> 因此没有任何输出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值