首页 > 财经旅游 > 正文

关于PHP缓冲,你知道多少?理解与实际运用

2019-08-14 14:30:08   来源:东方头条   评论:0

这一个月以来,我都忙着写后端代码,今天写这篇文单呢,主要是因为我觉得有必要来聊聊关于PHP缓冲这个概念以及它在项目中的运用。PHP缓冲是什么东西?

很多人都没有听过这个,包括工作过一段时间的PHP程序员都没有。我们看到的见面渲染出来的效果是第一时间的吗?有的是,有的不是。首先,缓冲区这个东西里面的东西不会第一时间输出到客户端,如果你打开它的话。

缓冲在应用程序中最主要的作用无非就两种,其一是为了减轻高速运转CPU的压力,其二则是用来解决I/O设备缓慢的弊端,这在很多地方都派上了用场。当我们要了解关于PHP缓冲区的知识时,首先得知道入口在哪儿。

从缓冲到输出的过程

当PHP程序在运行输出操作时,程序本身会自动将内容放入缓冲区,PHP接收到输出指令时会将内容输出给服务器,这里以apache服务器为例,那么服务器又会将内容缓冲到自身的缓冲区内,等接到apache输出指令时,再将内容输出到客户端。

从这个过程中,可以看到,一个缓冲区的内容想要输出到客户端,必须先到PHP自身的缓冲区转到apache,再到客户端展示出来。这是一个很重要的流程跟概念。PHP缓冲起到哪些作用?

有没有发现当我们在做文件流下载时通常会输出一些内容(里面可能包含自定义的参数,如果使用了header方法,且没有缓冲区的话,客户端会收到关于报错信息的response。因为,如果没有用缓冲的话,那么在第一次输出内容时会立即执行;第二种就是输出内容后,又设置了header信息。

此时,如果没有缓冲的话,则前端客户端会收到一条错误消息,提示关于已经有过header了,因为之前输出的内容会自动带header到客户端,而缓冲区的实现则可以实现输出内容,又可以设置header部分的内容,因为缓冲区输出的跟header是不冲突的,当header设置时,PHP会直接将消息推到apache然后传给客户端,而要传输的数据则会先到缓冲区等待发送,故不影响。

当传输文件过大时,没有缓冲区的话那是需要一次性读完后,再一次性传给客户端,这样的体验太差了,并且PHP的默认配置memory_limit也不支持,因为这个默认值是8M,也就是说最大的传输数据大小值为8M,为了避免此配置冲突,缓冲可以分片发送,每读取一部分就放缓冲区再进行传输到客户端。

如果做过静态文件的优化就会明白,静态处理是不需要PHP程序每次都去处理的,第一次处理过后就放入到缓冲区了,当下次来访问此静态页面时服务器会自动从缓存里取,而这就需要用到缓冲区去设置了。

关于PHP缓冲配置的几个选项

1、output_buffering

这个配置是PHP本身的缓冲区配置,有三个值,分别是on/off/某一个具体字节大小

on 顾名思义是开启缓冲区

off 是关闭

最后一个意思是可以写具体的某个字节大小,与此同时会自动开启缓冲区,也就是说到了这个大小的字节时会自动输出数据到apache,也叫刷新,清空缓冲区

2、implicit_flush

这个就是负责配置apache缓冲区的,两个配置参数on/off

on 开启的话,会自动刷新缓冲区将数据输出给客户端

off 则相反,需要等待传输指令,也就是下令传输到客户端,不会自动执行PHP操作关于缓冲区的函数

ob_implicit_flush 是否自动刷新缓冲区,注意这个是apache服务器的

flush 刷新指令,或者说是传输指令,让apache服务器清空,刷新,传输数据到客户端

ob_start 打开缓冲区,这个函数一运行,php.ini配置文件里的output_buffering将失效

ob_flush 指令,将通知php本身缓冲区传输到apache服务器

ob_clean 清除缓冲区内容

ob_end_clean 清除并关闭缓冲区

ob_end_flush 传输数据到apache服务器,然后关闭缓冲区

ob_get_clean 获取缓冲区内容并关闭缓冲区

ob_get_contents 获取输出缓冲区里的内容

ob_get_flush 获取缓冲区里的内容,并且发送到apache服务器

ob_get_length 获取缓冲区里内容长度

ob_list_handlers 运行ob_start函数的回调函数名称

ob_gzhandler 运行ob_start函数的回调函数名称,注意该函数在写入缓冲区之前会对内容进行gzip与zlib压缩处理

实际应用的问题

这里说几个实际中用到时发生的问题,比如nginx服务器有配置fastcgi_buffer_size 4k 也就是说只有当缓冲区到了4K时才会刷新输出,所以当你调用flush函数时一定要注意,否则看不到效果。

关于apache模块mod_gzip,当你flush后通知apache刷新缓冲区,这时apache发现此模块开启是需要压缩,就会输到mod_gzip的缓冲区中去,这时候内容是不会立马到客户端的,需要注意一下这点,如无需要就不要开启,如果有需要压缩在传输的话建议使用ob_gzhandler

本文原创,未经允许不得转载!

  责任编辑:

今日推荐

习近平在第五届中国国际进口博览会开幕式上发表致辞

11月4日晚,国家主席习近平以视频方式出席在上海举行的第五届中国国际进口博览会开幕式并发表题为《共创开放繁荣的美好未来》的致辞。新华社记者 李学仁 摄[详细]

中国共产党第二十次全国代表大会闭幕会在京举行

10月22日,中国共产党第二十次全国代表大会闭幕会在北京人民大会堂举行。新华社记者 陈建力 摄[详细]

天天学习|中南海月刊(2022.09)

天天学习金色九月,喜迎丰收。9月,一个个瞬间令人难忘:主持中央深改委会议决定健全关键核心技术攻关新型举国体制;出席中央军委晋升上将军衔仪式颁发命令状;新冠肺炎疫情发生以来首次出访...[详细]