前言引入

先看下面的代码:    

这个代码,每次输出后都有sleep(1),表示程序执行暂定一秒,想象中浏览器应该是每隔1s钟,逐渐显示1到5的,然后事实情况确不是,浏览器访问的时候,等了5s种后,页面上一下子出现1-55个数字的。这是为啥?

  那么,我们能不能让浏览器每隔一秒钟逐步显示出1-5五个数字呢?

  在看一段代码:

神奇的事儿发生,我们在浏览器上看到的情况是每隔一秒钟出现一个数字。实现了上面的梦想。

上面的代码中多了个flush,怎么就可以了呢?

解释上面的情况,我们就要引入下面我要说明的php的ob缓存了。

OB的基本介绍

那ob是啥呢?

ob就是output_buffer(输出缓存)的简写。在浏览器请求一个php页面的过程中,经历了三个缓存

  1、ob缓存

  2、程序缓存

  3、浏览器缓存

上面第一个例子,之所以没有逐步输出数字,是因为在php端,把要输出的东西,全部先放到程序缓存,等全部处理完,在一起返回给浏览器,所以你看到的是同时打印1-5五个数字。

体验下OB

我们再来看看

运行下如下代码:

报了个警告:

为啥呢?哦,因为在header请求头函数钱不能有任何的输出。我前面有打印111,就不行了。

那我加上一个ob_start(),把输出缓存打开。代码:

神奇的发现,访问能正常打印出111222了,不报警告了。

这是为啥呢?

原因是这样的,通过ob_start()函数,开启了输出缓存,之后,echo 111,要输出的111没有直接进入程序缓存,而是被放入了ob输出缓存中,然后执行header函数的时候,这个放入的是程序缓存,之后的222,又放入了ob输出缓存。后面没有了代码,当前php代码执行完毕,ob缓存中的111和222再刷入程序缓存,这个时候,header是先于111和222在程序缓存中的,好比header在111222前面,就不会报错了。最后,程序缓存中的数据,再一起全部输出要浏览器。

OB总结

我们总结下关于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个空字符,保证浏览器能正常输出内容。

php的ob缓存详解的更多相关文章

  1. redis使用及配置之缓存详解

    redis使用及配置之缓存详解 1.Redis的介绍 Redis是一个Key-Value存储系统.它支持存储的value类型有:string(字符串),list(链表), set(无序集合),zset ...

  2. 【转】MySQL查询缓存详解

    [转]MySQL查询缓存详解 转自:https://www.cnblogs.com/Alight/p/3981999.html 相关文章:http://www.zsythink.net/archive ...

  3. MySQL查询缓存详解(总结)

    MySQL查询缓存详解(总结) 一.总结 一句话总结: mysql查询缓存还是可以用用试一试,但是更推荐分布式,比如redis/memcache之流,将数据库中查询的数据和查询语句以键值对的方式存进分 ...

  4. [面试专题]Web缓存详解

    Web缓存详解 标签(空格分隔): 缓存 缓存之于性能优化 请求更快:通过将内容缓存在本地浏览器或距离最近的缓存服务器(如CDN),在不影响网站交互的前提下可以大大加快网站加载速度. 降低服务器压力: ...

  5. Hibernate缓存简介和对比、一级缓存、二级缓存详解

    一.hibernate缓存简介 缓存的范围分为3类:  1.事务范围(单Session即一级缓存)     事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象 ...

  6. Bitmap之内存缓存和磁盘缓存详解

    原文首发于微信公众号:躬行之(jzman-blog) Android 中缓存的使用比较普遍,使用相应的缓存策略可以减少流量的消耗,也可以在一定程度上提高应用的性能,如加载网络图片的情况,不应该每次都从 ...

  7. PHP之Memcache缓存详解

         Mem:memory缩写(内存):内存缓存 1.  断电或者重启服务器内存数据即消失,即临时数据: Memcache默认端口:11211 存入方式:key=>>value    ...

  8. 浏览器缓存详解:expires,cache-control,last-modified,etag详细说明

    最近在对CDN进行优化,对浏览器缓存深入研究了一下,记录一下,方便后来者 画了一个草图: 每个状态的详细说明如下: 1.Last-Modified 在浏览器第一次请求某一个URL时,服务器端的返回状态 ...

  9. memcache缓存详解

    这篇文章主要介绍了PHP中的Memcache,从Memcache简介开始,详细讲解了如Memcache和memcached的区别.PHP的 Memcache所有操作方法.每个操作方法的详细解释等,需要 ...

随机推荐

  1. 3.SLB 回话保持功能分析

    参考文档: 七层会话保持 配置服务器Cookie会话保持常见问题四层监听  

  2. linux 内核中一个全局变量引发的性能问题

    为了调试一个功能,在一个内核模块中,增加了一个全局变量,用来统计自有skb池的申请情况. 因为是临时增加,所以没有考虑性能,一开始只是一个fail的统计,数量不多,也不太考虑是否有计数丢失的情况,毕竟 ...

  3. JS 实现分页打印

    在调用window.print()时,可以实现打印效果,但内容太多时要进行分页打印. 在样式中有规定几个打印的样式 page-break-before和page-break-after CSS属性并不 ...

  4. [PHP]快速实现:将二维数组转为一维数组

    如何将下面的二维数组转为一维数组. $msg = array( array( 'id'=>'45', 'name'=>'jack' ), array( 'id'=>'34', 'na ...

  5. EF 1

    安装框架: 在NuGet中安装ef框架,命令:Install-package EntityFramework 数据迁移: 在程序包管理器控制台,执行语句. 初始化: 1.Enable-Migratio ...

  6. HDFS中的集中缓存管理详解

    一.背景 Hadoop设计之初借鉴GFS/MapReduce的思想:移动计算的成本远小于移动数据的成本.所以调度通常会尽可能将计算移动到拥有数据的节点上,在作业执行过程中,从HDFS角度看,计算和数据 ...

  7. tensorflow pip install 安装指定版本的包并指定安装源(速度会快很多)

    pip install tensorflow-gpu==1.3 pip install tensorflow-gpu==1.4 # pip install 命令行pip install -i http ...

  8. js高级-作用域链

    作用域链存放的就是 VO  AO 参数 变量 等

  9. js性能提高篇

    ,最后统一将DocumentFragment添加到页面. 该做法可以减少页面渲染dom元素的次数.经IE和Fx下测试,在append1000个元素时,效率能提高10%-30%

  10. MyBatis数据库连接的基本使用

    MyBatis部分: 本部分内容只主要体现Mybatis的特点. (1)MyBatis是什么? 开源的持久层框架,MyBatis的底层仍然是JDBC (2)编程步骤 step1 Maven项目 pom ...