关于PHP 缓冲区: ob_star , ob_get_contents

PHP ob_star ob_get_contents 细说
 
做者:田园花香 

关于PHP 缓冲区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()则会静默的清除服务端缓存的数据,而不会有任何数据或其余行为。web

相关文章
相关标签/搜索