关于PHP 缓冲区: ob_star , ob_get_contents
关于PHP 缓冲区
ob_start: 打开输出缓冲区,当缓冲区激活时,所有来自PHP程序的非头文件信息均不会发送,而是保存在内部缓冲区。
ob_get_contents: 返回内部缓冲区的内容。
ob_get_clean: 返回内部缓冲区的内容,并关闭缓冲区,(相当于ob_get_contents() and ob_end_clean())。
ob_get_flush: 返回内部缓冲区的内容,并关闭缓冲区,再释放内部缓冲区的内容。相当于ob_end_flush() 并返回内部缓冲区内容。
ob_get_lenght: 返回内部缓冲区的长度,如果缓冲区未被激活,该函数返回FALSE。
ob_clean: 删除内部缓冲区的内容,但不关闭缓冲区,也就是说该语句之后的输出内容将会继续被添加至缓冲区。
ob_flush: 释放内部缓冲区的内容,并删除内部缓冲区的内容,但不关闭缓冲区。
flush: 刷新输出缓冲,将ob_flush 释放出来的内容,以及不在PHP 缓冲区的内容,全部输出至浏览器。
ob_end_clean: 删除内部缓冲区的内容,并关闭缓冲区。
ob_end_flush: 释放内部缓冲区的内容,并关闭缓冲区。
(这里只要带flush 都会输出)
ob_gzhandler: ob_start回调函数,用gzip 压缩缓冲区的内容。
ob_implicit_flush: 打开或关闭绝对刷新,默认为关闭。所谓绝对刷新,当有输出语句,比如说echo被执行时,便把输出直接发送到浏览器,而不再需要调用flush()或等到脚本结束时才输出。
注意事项:
一些Web服务器的output_buffering默认是4069字符或者更大,即输出内容必须达到4069字符服务器才会flush刷新输出缓冲,为 了确保flush有效,最好在ob_flush()函数前有以下语句:
print str_repeat(“ ”, 4096); //以确保到达output_buffering值。
ob_* 系列函数是操作PHP本身的输出缓冲区,所以,ob_flush只刷新PHP自身的缓冲区。而flush是刷新apache的缓冲区。所以,正确使用俩者的顺序是:先ob_flush,然后flush。ob_flush是把数据从PHP的缓冲中释放出来,flush是把缓冲内/外的数据全部发送到浏览器。
不要误认为用了ob_start()后,脚本的echo/print等输出就永远不会显示在浏览器上了。因为PHP脚本运行结束后,会自动刷新缓冲区并输出内容。
要先ob_start()再 flash否则报错 Message: ob_flush() [ref.outcontrol]: failed to flush buffer. No buffer to flush.
我们在说说ob_start的用法
ob_start([string output_callback]):这里可是设置一个回调函数,打开缓冲区之后,所有的输出信息不再直接发送掉浏览器,而是保存在输出缓冲区里面,可以用这个回调函数用于处理输出结果的信息.
比如:
function test($str){
return str_replace('php100','haha',$str);
}
ob_start('test');
echo 'hello php100';
ob_end_flush();
在上面的例子中,使用 echo() 的输出内容将会保存在输出缓冲区中,直到调用了 ob_end_flush()或者脚本运行终止, 然后输出信息由自定义的处理函数进行处理(替换里面的字符串)并返回结果。
buffer ---- flush()
buffer是一个内存地址空间,Linux系统默认大小一般为4096(1kb),即一 个内存页。主要用于存储速度不同步的设备或者优先级不同的 设备之间传办理数据的区域。通过buffer,可以使进程这间的相互等待变少。这里说一个通俗一点的例子,你打开文本编辑器编辑一个文件的时候,你每输入 一个字符,操作系统并不会立即把这个字符直接写入到磁盘,而是先写入到buffer,当写满了一个buffer的时候,才会把buffer中的数据写入磁 盘,当然当调用内核函数flush()的时候,强制要求把buffer中的脏数据写回磁盘。
同样的道理,当执行echo,print的时 候,输出并没有立即通过tcp传给客户端浏览器显示, 而是将数据写入php buffer。php output_buffering机制,意味在tcp buffer之前,建立了一新的队列,数据必须经过该队列。当一个php buffer写满的时候,脚本进程会将php buffer中的输出数据交给系统内核交由tcp传给浏览器显示。所以,数据会依次写到这几个地方echo/pring -> php buffer -> tcp buffer -> browser
php output_buffering --- ob_flush()
默 认情况下,php buffer是开启的,而且该buffer默认值是4096,即1kb。你可以通过在php.ini配置文件中找到output_buffering配 置.当echo,print等输出用户数据的时候,输出数据都会写入到php output_buffering中,直到output_buffering写满,会将这些数据通过tcp传送给浏览器显示。你也可以通过 ob_start()手动激活php output_buffering机制,使得即便输出超过了1kb数据,也不真的把数据交给tcp传给浏览器,因为ob_start()将php buffer空间设置到了足够大 。只有直到脚本结束,或者调用ob_end_flush函数,才会把数据发送给客户端浏览器。
这 两个函数的使用怕是很多人最迷惑的一个问题,手册上对两个函数的解释也语焉不详,没有明确的指出它们的区别,似乎二者的功能都是刷新输出缓存。但在我们 文章一开始的代码中如果讲fush()替换成ob_flush(),程序就再不能正确执行了。显然,它们是有区别的,否则也手册中直接说明其中一个是另外 一个函数的别名即可了,没必要分别说明。那么它们的区别到底是什么呢?
在没有开启缓存时,脚本输出的内容都在服务器端处于等待输出的状态 ,flush()可以将等待输出的内容立即发送到客户端。
开 启缓存后,脚本输出的内容存入了输出缓存中 ,这时没有处于等待输出状态的内容,你直接使用flush()不会向客户端发出任何内容。而 ob_flush()的作用就是将本来存在输出缓存中的内容取出来,设置为等待输出状态,但不会直接发送到客户端 ,这时你就需要先使用 ob_flush()再使用flush(),客户端才能立即获得脚本的输出。
一. flush和ob_flush的正确顺序,正确应是,先ob_flush再flush,如下:
ob_flush();
flush();
如果Web服务器的操作系统是windows系统,那顺序颠倒或者不使用ob_flush()也不会出现问题。[有待求证 ] 但是在Linux系统上就无法刷新输出缓冲。
output buffering函数
1.bool ob_start ([ callback $output_callback [, int $chunk_size [, bool $erase ]]] )
激活output_buffering机制。一旦激活,脚本输出不再直接出给浏览器,而是先暂时写入php buffer内存区域。
php默认开启output_buffering机制,只不过,通过调用ob_start()函数据output_buffering值扩展到足够 大 。也可以指定$chunk_size来指定output_buffering的值。$chunk_size默认值是0,表示直到脚本运行结束,php buffer中的数据才会发送到浏览器。如果你设置了$chunk_size的大小 ,则表示只要buffer中数据长度达到了该值,就会将buffer中 的数据发送给浏览器。
当然,你可以通过指定$ouput_callback,来处理buffer中的数据。比如函数ob_gzhandler,将buffer中的数据压缩后再传送给浏览器。
第三个参数:是否擦除缓存,可选,默认是true,如果设置为false,则在脚本执行结束前,缓存都不会被清除。
2.ob_get_contents
获取一份php buffer中的数据拷贝。值得注意的是,你应该在ob_end_clean()函数调用前调用该函数,否则ob_get_contents()返回一个空字符中。
可以使用ob_get_contents()以字符串形式获取服务端缓存的数据,
使用ob_end_flush()则会输出被缓存起来的数据,并关闭缓存。
而使用ob_end_clean()则会静默的清除服务端缓存的数据,而不会有任何数据或其他行为。
服务端的缓存是堆叠起来的,也就是说你在开启了ob_start()后,关闭之前,在其内部还 可以开启另外一个缓存ob_start()。
不过你也要务必保证关闭缓存的操作和开启缓存的操作数量一样多。
ob_start() 可以指定一个回调函数来处理缓存数据,如果一个ob_start()内部嵌套了另一个ob_start(),我们假定,外层的ob_start(),编号 是A,内层的ob_start()编号是B,它们各自制定了一个回调函数分别是functionA和functionB,那么在缓存B中的数据输出时,它 会先辈funcitonB回调函数处理,再交给外层的functionA回调函数处理,之后才能输出到客户端。
另外,手册说,对于某些web服务器,比如apache,在使用回调函数有可能会改变程序当前的工作目录,解决方法是在回调函数中自行手动把工作目录修改回来,用chdir函数,这点似乎不常遇到,遇到的时候记得去查手册吧。
3.ob_end_flush与ob_end_clean
这 二个函数有点相似,都会关闭ouptu_buffering机制。但不同的是,ob_end_flush只是把php buffer中的数据冲(flush/send)到客户端浏览器,而ob_clean_clean将php bufeer中的数据清空(erase),但不发送给客户端浏览器。
ob_end_flush调用之前 ,php buffer中的数据依然存在,ob_get_contents()依然可以获取php buffer中的数据拷贝。
而ob_end_flush()调用之后 ob_get_contents()取到的是空字符串,同时浏览器也接收不到输出,即 没有任何输出。
可以使用ob_get_contents()以字符串形式获取服务端缓存的数据,使用ob_end_flush()则会输出被缓存起来的数据,并关闭缓存。
而使用ob_end_clean()则会静默的清除服务端缓存的数据,而不会有任何数据或其他行为。
关于PHP 缓冲区: ob_star , ob_get_contents的更多相关文章
- PHP的输出缓冲区(转)
什么是缓冲区?简单而言,缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.至于为什么要有缓冲区,这是一个很广泛的问题,如果有兴趣,可以在网山找下资料.其实缓冲区最本质的作用就是,协调 ...
- 关于header('location:url')的一些说明,php缓冲区
网上搜索header('location:url')的用法,得到如下三个结论: 1. location和“:”号间不能有空格,否则会出错. 2. 在用header前不能有任何的输出. 3. heade ...
- PHP的输出缓冲区
什么是缓冲区?简单而言,缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.至于为什么要有缓冲区,这是一个很广泛的问题,如果有兴趣,可以在网山找下资料.其实缓冲区最本质的作用就是,协调 ...
- 关于PHP 缓冲区
最权威的资料:http://php.net/manual/en/function.flush.php 里面有全世界的开发者的留言.常见问题都有讨论. 再说一下PHP 缓冲区相关的. web服务器 如 ...
- php 下载文件代码段
/** * 下载 * @param [type] $url [description] * @param string $filename [description] * @return [type] ...
- PHP输出缓冲(Output Buffering)
什么是缓冲区? 简单而言,缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.至于为什么要有缓冲区,这是一个很广泛的问题~其实缓冲区最本质的作用就是,协调高速CPU和相对缓慢的IO设备 ...
- php缓冲区详解
什么是缓冲区(buffer)? 简单而言,缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.至于为什么要有缓冲区,这是一个很广泛的问题,如果有兴趣,可以在网山找下资料. 其实缓冲区最 ...
- php函数ob_start()、ob_end_clean()、ob_get_contents()
下面3个函数的用法 ob_get_contents() - 返回输出缓冲区的内容 ob_flush() - 冲刷出(送出)输出缓冲区中的内容 ob_clean() - 清空(擦掉)输出缓冲区 ob_e ...
- 用include()和ob_get_contents( )方法 生成静态文件
1. 生成静态文件可以在打开缓冲区的前提下,用include()方法去包含要执行的动态文件,这样该动态文件就会在缓冲区中执行,执行完毕后的静态HTML代码就保存在缓冲区中,然后用ob_get_cont ...
随机推荐
- C# [GDI+] [API] Get Image bytes Length
MemoryBMP "{b96b3caa-0728-11d3-9d7b-0000f81ef32e}" 2 Bmp "{b96b3cab-0728-11d3-9d7b-00 ...
- python之路-变量
变量定义的规则: - 变量名只能是字母.数字.或下划线的任意组合 - 变量名的第一个字符不能是数字 - 以下关键字不能声明为变量名 ['and','as','assert','break','cla ...
- 【webpack学习笔记】a06-生产环境和开发环境配置
生产环境和开发环境的配置目标不一样,生产环境主要是让文件压缩得更小,更优化资源,改善加载时间. 而开发环境,主要是要开发更方便,更节省时间,比如调试比如自动刷新. 所以可以分开配置不同的开发环境,然后 ...
- xcode10关于clang -lstdc++.6.0.9报错问题
因为xcode10已经废弃了libstdc++.6.0.9这个库,所以只需要在你的工程中删除这个库,然后添加libc++这个库就可以了.别的没什么,如果xcode10报错mutable开头的,大部分是 ...
- css书写规范以及如何写出赏心悦目的代码
css书写规范: 1. 编码统一为utf-8;2. 协作开发及分工: i根据各个模块, 同时根据页面相似程序, 事先写好大体框架文件,同时根据页面相似程序,事先写好大体框架文件.共用css文件base ...
- Java——重写
重写面向对象编程的三大特征之一 1.子类重写了父类的方法,则使用子类创建的对象调用该方法时,调用的是重写后的方法,即子类中的方法 2.子类重写父类方法需满足以下条件: (1)方法名和参数列表: 子类重 ...
- Git问题总结
1 git push origin master 提示Everything up-to-date 表示本地仓库和远程仓库是一致的,没有更新,需要检查自己的提交. 2 git push origin m ...
- sqlloader 往数据库导数据提示数据文件的字段超出最大长度
当我们用sqlloader往数据库导数据提示被拒绝,数据文件的字段超出最大长度.但是我们不管怎么改提示字段的长度的时候仍然提示超出最大长度. 这个是因为ctl文件中默认为char256,超过256需要 ...
- Delphi 对ini文件的操作
界面如图: 代码如下: unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Vari ...
- JAVA 平时作业一
public class Print { public static void main (String arg[]) { for(int i=0;i<16;i++) { for(int j=0 ...