先看下面的代码:
这个代码,每次输出后都有sleep(1),表示程序执行暂定一秒,想象中浏览器应该是每隔1s钟,逐渐显示1到5的,然后事实情况确不是,浏览器访问的时候,等了5s种后,页面上一下子出现1-55个数字的。这是为啥?
那么,我们能不能让浏览器每隔一秒钟逐步显示出1-5五个数字呢?
在看一段代码:
神奇的事儿发生,我们在浏览器上看到的情况是每隔一秒钟出现一个数字。实现了上面的梦想。
上面的代码中多了个flush,怎么就可以了呢?
解释上面的情况,我们就要引入下面我要说明的php的ob缓存了。
那ob是啥呢?
ob就是output_buffer(输出缓存)的简写。在浏览器请求一个php页面的过程中,经历了三个缓存
1、ob缓存
2、程序缓存
3、浏览器缓存
上面第一个例子,之所以没有逐步输出数字,是因为在php端,把要输出的东西,全部先放到程序缓存,等全部处理完,在一起返回给浏览器,所以你看到的是同时打印1-5五个数字。
我们再来看看
运行下如下代码:
报了个警告:
为啥呢?哦,因为在header请求头函数钱不能有任何的输出。我前面有打印111,就不行了。
那我加上一个ob_start(),把输出缓存打开。代码:
神奇的发现,访问能正常打印出111222了,不报警告了。
这是为啥呢?
原因是这样的,通过ob_start()函数,开启了输出缓存,之后,echo 111,要输出的111没有直接进入程序缓存,而是被放入了ob输出缓存中,然后执行header函数的时候,这个放入的是程序缓存,之后的222,又放入了ob输出缓存。后面没有了代码,当前php代码执行完毕,ob缓存中的111和222再刷入程序缓存,这个时候,header是先于111和222在程序缓存中的,好比header在111222前面,就不会报错了。最后,程序缓存中的数据,再一起全部输出要浏览器。
我们总结下关于ob的几个知识点
1、 在程序中,如果我们开启了ob缓存,那么页面上的输出(打印)部分数据,首先会放入ob缓存中。最后在输入程序缓存输出去浏览器。
2、我们开启ob缓存的两个方法:
1、通过php.ini,找到output_buffering选项,=Off:关闭 =On:开启 =4096:开启,并且缓存空间为4096个字节
通过配置文件开启,作用于全部php页面
2、在当前页面使用ob_start()函数开启,仅作用于当前php页面。
3、当php执行到最后,则会自动把ob缓存中的数据(如果有的话),强制刷新到程序缓存,然后通过web服务器apache等,对数据封装成http响应包,返回给浏览器。
4、如果没有ob缓存,那么要输出的所有数据直接放入程序缓存
5、header信息,不管你有没有开启ob缓存,总是被放入程序缓存
在ob中,我们常用的几个函数:
ob_start() //打开ob缓存
ob_clearn() //清除ob缓存中的内容,但是不关闭ob
ob_end_clearn() //清除ob缓存中的内容,并且关闭ob
ob_flush() //把ob缓存中的内容,刷新到程序缓存,但是不关闭ob
ob_end_flush() //把ob缓存中的内容,刷新到程序缓存,并且关闭ob
ob_get_contents() //获取ob缓存中的内容
要怎么去理解整几个函数呢,我们还是看几个例子吧!
例子1:
上面的代码页面输出是啥?111222333
文件里打印的是啥? 111222
我们逐行分析:
8:开启ob缓存,后面的输出都会被放入ob缓存
9:111放入ob缓存
10:header放入程序缓存
11:222放入ob缓存
12:此时ob缓存中有111222,被获取到$ob_str中,所以文件里打印的是111222(明白了)
14:333放入ob缓存
最后代码执行完毕,此时ob缓存中是111222333,被全部自动刷新到程序缓存,输入到浏览器
例子2:
浏览器输出:222333 最先放入缓存的111在ob_get_contents和刷新到程序缓存的时候被ob_clean清理了
文件打印:222
例子3:
浏览器输出:222333
文件打印:空 因为获取的时候,ob缓存被清空了并且关闭
例子4:
浏览器输入:报warning。 原因:111先放入ob缓存,紧接着ob_end_flush把ob中的111刷新到程序缓存,接下来header才放入程序缓存,结果造型header前有输出
文件打印:空
例子5:
浏览器输出:报错,和上例子一样
文件打印:
原因:ob没有关闭,把下面的报错信息和222都放入了ob缓存。这里大家注意到了,ob缓存的内容,不仅仅是页面的打印部分,应该是说页面最终返回到浏览器的所有内容。因为这个,我们可以用ob来做页面静态化
例子6:flush() 这个函数在手册上描述的不太准备,其实他的作用是把 ob程序缓存的内容 刷新到 浏览器缓存
上面文章开头就是用到了它。我们要知道,浏览器能看到内容,就是把程序缓存刷新到浏览器缓存的结果,一般这个过程都是在当当前代码全部执行完毕后,先把ob缓存自动刷新到程序缓存,再自动把程序缓存自动刷新到浏览器缓存,最后我们在浏览器上看到结果。
文章开头的例子中,我们使用了flush(),就可以让代码还没有执行完毕,就强制把程序缓存中的内容刷新到浏览器,直接在浏览器上可见。所以出现了1-5每秒出现一个数字的情况。
那为啥前面还加了呢?因为要让浏览器显示内容,浏览器的缓存必须达到一定的字节数,所以我们在打印1的时候,上面先放1024个空字符,保证浏览器能正常输出内容。