资讯专栏INFORMATION COLUMN

【modernPHP专题(10)】理解output buffer

kelvinlee / 323人阅读

摘要:磁盘高速缓存操作系统中使用磁盘高速缓存技术来提高磁盘的速度,对高速缓存复制的访问要比原始数据访问更为高效。因此,磁盘高速缓存在逻辑上属于磁盘,物理上则是驻留在内存中的盘块。

1. 磁盘高速缓存(Disk Cache)

操作系统中使用磁盘高速缓存技术来提高磁盘的I/O速度,对高速缓存复制的访问要比原始数据访问更为高效。例如,正在运行的进程的指令既存储在磁盘上,也存储在物理内存上,也被复制到CPU的二级和一级高速缓存中。

不过,磁盘高速缓存技术不同于通常意义下的介于CPU与内存之间的小容量高速存储器,而是 指利用内存中的存储空间来暂存从磁盘中读出的一系列盘块中的信息。因此,磁盘高速缓存在逻辑上属于磁盘,物理上则是驻留在内存中的盘块。

高速缓存在内存中分为两种形式:一种是在内存中开辟一个多带带的存储空间作为磁速缓存,大小固定;另一种是把未利用的内存空间作为一个缓沖池,供请求分页系统和磁盘I/O时共享。

2. 缓冲区(Buffer)

高速设备(如CPU)和低速设备(如磁盘)的通信都要经过缓存区,高速设备永远不会直接去访问低速设备。所以缓冲区是计算机中暂时存放输出或输入信息的内存区域。缓和高速部件和低速部件之间通信速度不匹配的矛盾。

3. PHP输出缓冲区

输出缓冲区顾名思义是输出信息暂时存放的内存区域,通过ob_*系列函数来控制输出缓冲区。

当php脚本执行结束(会自动调用ob_flush())或强制刷新(手动调用ob_fush())缓冲区后,才会把数据发送给Nginx fastcgi客户端。当然PHP还有其他的缓冲区,比如字符串缓冲区finfo::buffer。

PHP的输出缓冲区默认是开启,并且大小是4096字节。开启后对所有php页面都生效。

另外一种在页面中多带带开启缓冲区的办法是ob_start()函数。

// ob_start()有三个参数,$chunk_size是用来设置缓冲区大小,可以设置0-4096,默认是0表示大小不限。
bool ob_start ([ callback $output_callback [, int $chunk_size [, bool $erase ]]] )

注意:一个ob_start()就是一个新的缓冲区,缓冲区是互相叠加的

4. Nginx缓冲区

Nginx默认不会实时把php-fpm响应的数据返回给客户端,而是暂存在Nginx缓冲区中。当php脚本执行结束(自动调用flush())或强制刷新(手动flush())缓冲区后,才会把数据发送给客户端。

5. 浏览器缓冲区

浏览器默认不会实时显示从Nginx返回的数据,而是把接受到的数据暂存在浏览器缓冲区中,当缓冲区满后,才会开始显示。不同的浏览器缓冲区大小不同。实际测试发现Mac 下chrome和safari都需要输出1024字节。没有找到刷新缓冲区的办法,可以通过发送额外的空格来解决。

或者通过curl来请求,通过–no-buffer来禁用curl buffer。

curl "niliu.me" --no_buffer
实例篇 实时输出
// ob_get_level() 返回多少个缓冲区(因为缓冲区是叠加的,也可以称之为多级缓冲区)
var_dump(ob_get_level()); // out: 1, 一级缓冲区
if (ob_get_level() == 0) {
    // 如果没缓冲区,就开启新的PHP缓冲区
    // 默认会有一块缓冲区,默认的缓冲区其实是很小的,所以不用什么str_pad撑满
    ob_start();
}
for ($i = 0;$i < 10;$i ++) {
    echo "Line to show.";
    // nginx fastcgi缓冲区大小是4K,需要发送额外4K空格;
    //  echo str_pad("",4096)."
";

    // php缓存刷入Apache/nginx
    ob_flush();

    // 从Apache/nginx刷到浏览器
    flush();
    //此时,浏览器应该显示了, 如果浏览器不是即时显示,就输空格撑满浏览器buffer
    // echo str_repeat(" ",1024);

    sleep(2);
}
echo "Done.";
ob_end_flush();  // 冲刷出(送出)输出缓冲区内容并关闭缓冲
var_dump(ob_get_level()); // out: 0, 无缓冲区
模板渲染
class Template{
    /**
     * 渲染方法
     *
     * @access public
     * @param obj 信息类
     * @param string 模板文件名
     */
    public function render($context, $tpl){
        $closure = function($tpl){
            ob_start();
            include $tpl;
            return ob_end_flush();
        };
         
        // PHP7: $closure->call($context, $tpl);
        $closure = $closure->bindTo($context, $context);
        $closure($tpl);
    }
}
静态页生成
// 开启缓冲区
ob_start();

// 业务逻辑省略
// .....

$this->assign("模板中的变量分配");
$tpl->display("default_1.tpl");

// 获取缓冲区中解析变量后的模板
$html = ob_get_contents();
// 清空并关闭缓冲区
ob_end_clean();

// 把html写入文件
// 业务逻辑省略 ...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31455.html

相关文章

  • modernPHP专题(8)】匿名函数和闭包

    摘要:匿名函数输出可以直接将匿名函数进行传递。报错,找不到变量之所以称为副本,是因为通过闭包传值到匿名函数内的变量值也是不能改变。该方法使用了一个作为回调函数。 匿名函数 // Example1 $func = function( $param ) { echo $param; }; $func( some string );//输出:some string // Example2...

    junnplus 评论0 收藏0
  • modernPHP专题(13)】ZendOpcache字节码缓存

    摘要:概述字节码缓存不是的新特性,有很多独立的扩展可以实现,比如和等,但是截至目前这些扩展都没有集成到内核,从开始,内置了字节码缓存功能,名为。开始之前,我们先来看看什么是字节码缓存,以及字节码缓存的作用是什么。该函数将重置整个字节码缓存。 概述 字节码缓存不是PHP的新特性,有很多独立的扩展可以实现,比如APC、eAccelerator和Xache等,但是截至目前这些扩展都没有集成到PHP...

    KevinYan 评论0 收藏0
  • modernPHP专题(3)】依赖注入与服务容器

    摘要:而依赖倒置原则的思想是,上层不应该依赖下层,应依赖接口。上面通过构造函数注入对象的方式,就是最简单的依赖注入当然注入不仅可以通过构造函数注入,也可以通过属性注入,上面你可以通过一个来动态为这个属性赋值。 依赖倒置和控制反转是一种编程思想,而依赖注入就是通过服务容器实现这种面向接口或者是面向抽象编程的思想 概念理解 依赖倒置原则 依赖倒置是一种软件设计思想,在传统软件中,上层代码依赖于下...

    terro 评论0 收藏0
  • modernPHP专题(7)】生成器语法

    摘要:通过生成器来生成关联数组下面每一行是用分号分割的字段组合,第一个字段将被用作键名。正常来说,产生的是一个,它的成员变量与函数不存在别名引用关系。关键字在的版本,生成器允许从其他生成器,可迭代对象或数组通过关键字来生成对应的值输出 一般你在迭代一组数据的时候,需要创建一个数据,假设数组很大,则会消耗很大性能,甚至造成内存不足。 //Fatal error: Allowed memory ...

    jackwang 评论0 收藏0
  • modernPHP专题(9)】匿名类

    摘要:复制当前闭包对象,绑定指定的对象和类作用域。类作用域,可以是对象,也可以是实例名称什么是匿名类先理解以下三个例子例闭包函数都是继承类返回匿名函数返回匿名函数,也就是闭包函数,所有闭包函数都是继承类输出例将一个匿名函数绑定到一个类中。 类结构 Closure { /* 方法 */ // 用于禁止实例化的构造函数 __construct ( void ) ...

    ninefive 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<