PHP 输出控制

默认情况下,输出一个字符串到浏览器,经过3个阶段PHP buffer->Tcp buffer->浏览器(IE浏览器有的版本也存在buffer)

PHP默认是打开输出缓冲的,在php.ini中可以配置output_buffering=4096(4kb,一个内存页),设置PHP输出缓冲大小

•flush — 刷新输出缓冲(按我的理解是刷新输出TCP bufer) •ob_clean — 清空(擦掉)输出缓冲区 •ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲 •ob_end_flush — 冲刷出(送出)输出缓冲区内容并关闭缓冲 •ob_flush — 冲刷出(送出)输出缓冲区中的内容 •ob_get_clean — 得到当前缓冲区的内容并删除当前输出缓。 •ob_get_contents — 返回输出缓冲区的内容 •ob_get_flush — 刷出(送出)缓冲区内容,以字符串形式返回内容,并关闭输出缓冲区。 •ob_get_length — 返回输出缓冲区内容的长度

(PHP 4, PHP 5, PHP 7)

ob_start — 打开输出控制缓冲

bool ob_start ([ callback $output_callback [, int $chunk_size [, bool $erase ]]] )

此函数将打开输出缓冲。当输出缓冲激活后,脚本将不会输出内容(除http标头外),相反需要输出的内容被存储在内部缓冲区中

由于IE有的版本会有浏览器buffer(256字节),以下代码均在chrome浏览器下运行

1. ob_start使用说明

ob_start('replace_content');
echo 'Kevin Durant go to Golden State Warriors!';
//David West go to Golden State Warriors!

function replace_content($content){
    return str_replace('Kevin Durant', 'David West', $content);
}

再看下面的代码

ob_end_clean();//必须关闭系统缓冲区
ob_start(null, 1);
for($i = 1; $i <=10; $i++){
    echo $i,'<br>';
    //ob_flush();
    flush();//输出TCP缓冲
    sleep(1);
}

PHP默认开启了一个输出缓冲区,所以先调用ob_end_clean关闭默认的输出缓冲。由于调用ob_start设置该缓冲区大小为1个字节,所以这段代码会每隔1秒输出。

再看下面的代码也可以做到这个效果

for($i = 1; $i <=10; $i++){
    echo $i,'<br>';
    ob_flush();
    flush();//输出TCP缓冲
    sleep(1);
}

使用了系统默认的输出缓冲区,此时缓冲区大小为默认的4096个字节,所以必须调用ob_flush刷新输出PHP缓冲内容.

2.输出过程

 //PHP默认缓冲区F
 1 ob_start();             //缓冲区A
 2 echo 'champion 1<br />';
 3 ob_start();             //缓冲区B
 4 echo 'champion 2<br />';
 5 ob_start();             //缓冲区C
 6 echo 'champion 3<br />';
 7 ob_end_clean();
 8 ob_end_flush();
 9 ob_end_clean();
10 $str = ob_get_contents();
11 echo $str;

运行结果: 没有输出任何东西

可以把整个缓冲区看作一个栈,有新的缓冲区被创建,则新的缓冲区成为栈顶缓冲区。有新内容输出则输出内容会被输出到栈顶的缓冲区。

本程序缓冲区层次: C->B->A->F

初始F:null

运行 1.ob_start(); 后,新建缓冲区A,此时整个缓冲区情况

A:null->F:null

运行 2.echo 'level 1<br />'; 后

内容输出到缓冲区A,此时整个缓冲区情况

A:’level 1<br />’ -> F:null

运行 3.ob_start(); 后,新建缓冲区B,此时整个缓冲区情况

B:null -> A:’level 1<br />’ -> F:null

运行 4.echo 'level 1<br /\>'; 后

内容输出到缓冲区B,此时整个缓冲区情况

B:’level 2<br />’ -> A: ‘level 1<br />’ -> F:null

以此类推建立缓冲区C,运行到 6.echo 'level 3<br />'; 后,此时整个缓冲区情况

C:’level 3<br />’ -> B:’level 2<br />’ -> A: ‘level 1<br />’ -> F:null

接着运行 7.ob_end_clean(); ,缓冲区C被清空且关闭,此时缓冲区情况

B:’level 2<br />’ -> A: ‘level 1<br />’ -> F:null

接着运行 8.ob_end_flush(); ,缓冲区B的内容输出到上一级的缓冲区且缓冲区B被关闭。此时缓冲区情况

A: ‘level 2<br /> level 1<br />’ -> F:null

接着运行 9.ob_end_clean(); ,缓冲区A被情况且关闭。A的内容还没有真正输出到缓冲区F中就被关闭了,最后只剩F:null,因此程序就没有任何输出了。

可使用ob_get_level()获取输出缓冲机制的嵌套级别

3.ob_clean(), ob_end_clean(),  ob_flush(),  ob_end_flush()的区别

开始真是傻傻分不清楚,简单的说ob_end_clean()和ob_end_flush()会关闭当前缓冲区,而ob_clean(),ob_flush()不会.

echo 'champion1<br>';
ob_start();
echo 'champion2<br>';
ob_end_clean();
var_dump(ob_get_contents());
echo 'champion1<br>';
ob_start();
echo 'champion2<br>';
ob_enb_clean();
var_dump(ob_get_contents());

相信你可以判断出输出的结果啦。

我们用GD库输出图片的时候,或者ajax接口输出数据之前我们应该使用ob_clean,因为ob_end_clean会关闭当前输出缓冲区,

很明显使用PHP输出缓冲程序效率会更高。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏python3

python 文件操作2

Somehow, it seems the love I knew was always the most destructive kind

1131
来自专栏Android随笔

mac学习笔记

在打开的文本文件中,添加如下内容(/XXX/XXX/platform-tools/为你的adb路径)

762
来自专栏nummy

sphinx入门指南【1】快速入门

包含.rst文件的根目录称之为源文件目录,目录中还包含sphinx的配置文件conf.py。

1484
来自专栏Python攻城狮

Python操作redis

1 .用户登录首先判断是否在redis缓存中,如果在redis缓存中,直接登录成功; 2 .若用户未在redis缓存,则访问Mysql,判...

1653
来自专栏深度学习之tensorflow实战篇

python 如何设置多线程

和多进程的思路类似,我们也可以实现对线程的创建,在Python中,使用threading包实现。参数如下: 构造方法: Thread(group=No...

2623
来自专栏大内老A

.NET Core的文件系统[4]:由EmbeddedFileProvider构建的内嵌(资源)文件系统

一个物理文件可以直接作为资源内嵌到编译生成的程序集中。借助于EmbeddedFileProvider,我们可以统一的编程方式来读取内嵌于某个程序集中的资源文件,...

2168
来自专栏逍遥剑客的游戏开发

Tiled源码分析(四): 插件机制

2297
来自专栏玩转JavaEE

elasticsearch修改数据

上篇文档向读者介绍了Elasticsearch提供的强大的REST API的基本用法,不过这些API的用法都很基础,本文将和读者继续分享更多的API。

2452
来自专栏崔庆才的专栏

利用 Flask+Redis 维护 IP 代理池

目前有很多网站提供免费代理,而且种类齐全,比如各个地区、各个匿名级别的都有,不过质量实在不敢恭维,毕竟都是免费公开的,可能一个代理无数个人在用也说不定。所以我们...

2.2K0
来自专栏深度学习之tensorflow实战篇

python(Django之html模板继承)

Django之html模板继承简单案例 1 构建母板,确定不变内容和可变内容 ? 2 构建子板,对可变内容进行填充 ? 结果: ? Dja...

3885

扫码关注云+社区