PHP的buffer是这样的:

输出的字符串 => PHP buffer => 等待输出 => web 服务器的缓冲区 => tcp 缓冲区 => 客户端。过程其实相当的复杂。

大概的工作机制:

bool ob_start    ([ callback $output_callback   [, int $chunk_size   [, bool $erase  ]]] ) 这个函数我关键要强调一下第二个参数:

如果可选参数 chunk_size 被赋值了,在任何一个能引起缓冲区的长度等于或超过 chunk_size 的输出操作后,缓冲区都会被刷送。  默认值 0 意味着脚本结束之后,缓冲区会被刷送,其余的特殊值可以将 chunk_size从 1 设定到 4096。

这个参数默认是0.

还有一点,缓冲区是可以嵌套的。这点非常关键。比如你调用了两次ob_start ,就会创建用两个缓冲区。第二次创建的缓冲区,会写入第一次创建的缓冲区,而ob_start 创建的缓冲区,总是会写入output_buffering =ON 时候系统自动创建的缓冲区。

我们再来看一下:ob_end_flush ,这个函数的作用是把最后一次打开的缓冲区关闭掉,并把内容送入下一个缓冲区。如果下一个缓冲区没有,就进入等待输出的状态了。

flush是刷新等待输出的内容去浏览器。前提是内容是等待输出的状态了,而不是在缓冲区中,它不会影响缓冲区的内容。

再来看你的代码:

如果output_buffering = On ,那么系统会默认创建一个缓冲区,这个大小一般是2K. ob_end_flush的内容会进入这个缓冲区,而不会进入输出等待。所以调用flush一点效果都没有。直到脚本结束,PHP送出所有的内容。

如果output_buffering = Off ob_end_flush的内容会进入输出等待状态,这个时候flush一下,内容就能输出了。

当然,这个只是PHP这一端的情况分析。

还会有其他的因数影响最终的输出:

个别web服务器程序,特别是Win32下的web服务器程序,在发送结果到浏览器之前,仍然会缓存脚本的输出,直到程序结束为止。

有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。

甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape 浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在接受到 </table> 标记之前,不会显示出整个表格。

一些版本的 Microsoft Internet Explorer 只有当接受到的256个字节以后才开始显示该页面,所以必须发送一些额外的空格来让这些浏览器显示页面内容。

PHP buffer的机制的更多相关文章

  1. Linux内存管理Swap和Buffer Cache机制

    Linux内存管理Swap和Buffer Cache机制 一个完整的Linux系统主要有存储管理,内存管理,文件系统和进程管理等几方面组成,贴出一些以前学习过的一个很好的文章.与大家共享!以下主要说明 ...

  2. Log Buffer

    Log Buffer 一.Log Buffer的引入 Oracle有一个原则:只要是已经提交的数据,就不会丢失,保证数据库的一致性.这该如何实现?事物提交时,直接写入dbf中,效率是极低的.因为直接写 ...

  3. Node闲谈之Buffer

    在刚接触Nodejs的时候,有些概念总让学前端的我感到困惑(虽然大学的时候也是在搞后端,世界上最好的语言,you know).我可以很快理解File System,Path等带有明显功能的模块,却一下 ...

  4. Linux内存管理机制简析

    Linux内存管理机制简析 本文对Linux内存管理机制做一个简单的分析,试图让你快速理解Linux一些内存管理的概念并有效的利用一些管理方法. NUMA Linux 2.6开始支持NUMA( Non ...

  5. Python使用Zero-Copy和Buffer Protocol实现高性能编程

    无论你程序是做什么的,它经常都需要处理大量的数据.这些数据大部分表现形式为strings(字符串).然而,当你对字符串大批量的拷贝,切片和修改操作时是相当低效的.为什么? 让我们假设一个读取二进制数据 ...

  6. MySql 缓冲池(buffer pool) 和 写缓存(change buffer) 转

    应用系统分层架构,为了加速数据访问,会把最常访问的数据,放在缓存(cache)里,避免每次都去访问数据库. 操作系统,会有缓冲池(buffer pool)机制,避免每次访问磁盘,以加速数据的访问. M ...

  7. 普通索引和唯一索引如何选择(谈谈change buffer)

    假设有一张市民表(本篇只需要用其中的name和id_card字段,有兴趣的可以翻看“索引”篇,里面有建表语句) 每个人都有一个唯一的身份证号,且业务代码已经保证不会重复. 由于业务需求,市民需要按身份 ...

  8. .NET程序优化

    一.数据库操作 1. 用完马上关闭数据库连接 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证, 比较耗费服务器资 源.ASP.NET 中提供了连 ...

  9. Actor的原理

    先从著名的c10k问题谈起.有一个叫Dan Kegel的人在网上(http://www.kegel.com/c10k.html)提出:现在的硬件应该能够让一台机器支持10000个并发的client.然 ...

随机推荐

  1. WebGL开发入门

    ­­­Getting started with WebGL development WebGL开发入门 What is Unity WebGL? 什么是Unity WebGL? The WebGL b ...

  2. python增量爬虫pyspider

    1.为了能够将爬取到的数据存入本地数据库,现在本地创建一个MySQL数据库example,然后 在数据库中建立一张表格test,示例如下: DROP TABLE IF EXISTS `test`; C ...

  3. SkipList跳表基本原理

    为什么选择跳表 目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay Tree, Treep等. 想象一下,给你一张草稿纸,一只笔,一个编辑器,你能立即实现一颗红黑树,或者AVL树 出来吗 ...

  4. ABB-robotstudio离线编程-Smart组件资料-笔记

    Smart组件 目录: 1.“信号与属性”子组件. 2.“参数与建模”子组件. 3.“传感器”子组件. 4.“动作”子组件. 5.“本体”子组件. 6.“其他”子组件. 一.“信号与属牲”子组件 1. ...

  5. css入门基础知识

    一.CSS常用选择器 /*CSS注释*/ /*CSS修改页面中的所有标签必须借助选择器选中. 选择器中可以写多对CSS属性:每个属性名与属性值之间用:分隔,多对属性之间,必须用;分隔 选择器{ 属性1 ...

  6. 转:【Java并发编程】之二:线程中断(含代码)

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17091267 使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应 ...

  7. make: Nothing to be done for 'all' 解决方法

    make: Nothing to be done for 'all' 解决方法 1.这句提示是说明你已经编译好了,而且没有对代码进行任何改动. 若想重新编译,可以先删除以前编译产生的目标文件:make ...

  8. 复杂关联SQL的优化

    昨天处理了一则复杂关联SQL的优化,这类SQL的优化往往考虑以下四点: 第一.查询所返回的结果集,通常查询返回的结果集很少,是有信心进行优化的: 第二.驱动表的选择至关重要,通过查看执行计划,可以看到 ...

  9. 201521123071 《JAVA程序设计》第七周学习总结

    第7周-集合 1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 1.1 Iterator<E> iterator(); //iterator()返回一个实现了It ...

  10. 201521123114 《Java程序设计》第6周学习总结

    1. 本章学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 Q1.clone方法 1.1 Object ...