从php的缓冲区说起

简介:

大家应该都知道php文件最终在浏览器上显示,走过3个缓冲阶段:
php buffer=》web server buffer=》浏览器buffer。

先从php buffer开始讲起。
php buffer
php运行的结果先放入缓冲区(buffer),只有当缓冲区满了或者php运行完毕,才将数据输出去。

缓冲区是通过php.ini中的output_buffering变量控制。output_buffering的默认值是off,可以设置大于0的数值来打开buffer。
但是这里需要注意的是:
1)使用ini_set是无法修改buffer的设置。
2)不管php.ini中output_buffering设置,cli模式下的php始终默认是output buffering为关闭的。但是你可以通过ob_start()将buffer打开。

大家都说:ob_start()是将php buffer打开,ob_end_flush()是将php buffer关闭。但是php.ini中php buffer是关闭的,再次调用ob_end_flush()会报warning。

另外,ob_*系列的函数是操作php本身的输出缓冲区。可以使用ob_flush()将php 缓冲区的内容强制输出。

web server buffer
这里主要将apache和nginx的缓冲区。
1、apache buffer
当php的输出数据给apache服务器时,它也会做一层buffer(也将数据放入它的缓冲区,当缓冲区数据满或执行完毕时,才输出数据)。

若想关闭缓冲区,可以在php层使用flush()来强制将缓冲区数据输出。
fulsh() 的工作原理:在apache module的sapi下, flush会通过调用sapi_module的flush成员函数指针, 间接的调用apache的api: ap_rflush刷新apache的输出缓冲区, 当然手册中也说了, 有一些apache的其他模块, 可能会改变这个动作的结果.例如mod_gzip,可能自己进行输出缓冲区,这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。

2、nginx buffer
nginx使用fastcgi缓冲区来缓冲数据。很遗憾的是,fastcgi是强制将buffer打开的,无法关闭缓冲区。

有人有可能会想,无法关闭可以将buffer设置的足够小,来使缓冲数据输出,达到无缓冲的效果。但是这个想法无法实现。
原因一:fastcgi buffer无法识别小于1k的数值。
原因二:受参数之间大小关系的影响。

具体可以看看fastcgi的一些buffer设置。
fastcgi_buffer_size是用来存储response的header数据。
fastcgi_buffers是用来存储response的内容数据.
fastcgi_busy_buffers_size是用来控制同时传输到客户端的buffer数量。一旦fastcgi_buffers设置的 buffer被写入,直到buffer里面的数据被完整的传输完(传输到客户端),这些buffer将会一直处在busy状态,我们不能对这些 buffer进行任何别的操作。所有处在busy状态的buffer size加起来不能超过fastcgi_busy_buffers_size。

参数之间大小关系:
fastcgi_busy_buffers_size<(all fastcgi_buffers - one buffer) 并且fastcgi_busy_buffers_size>=max (fastcgi_buffer_size, one fastcgi _buffers)。
例如,在nginx.conf配置中有:
fastcgi_buffers 4 128k
fastcgi_buffer_size 256k
那么fastcgi_busy_buffers_size<(4*128k - 4k) 并且fastcgi_busy_buffers_size>=max(256k, 128k)
其中,4k(one buffer的大小)是linux系统默认的缓存大小,即一个内存页。

若fastcgi_buffer_size设置的很小,会导致header过小的错误。你也同样无法保证设置的值会满足所有的情况。

要注意的是:
1)flush, 严格来讲, 这个只有在PHP做为apache的Module(handler或者filter)安装的时候, 才有实际作用. 它是刷新WebServer(可以认为特指apache)的缓冲区.所以在nginx下,flush()函数是无法起作用的。

browser buffer
在 php端无法关闭浏览器buffer(至少目前我没有研究出来,若有哪位高人研究出来了,请一定要记得分享)。为了使得数据及时输出,可以在发送真正内容 数据前,发送一些空格来填满浏览器的buffer。浏览器的buffer一满,就会将其他新输出的数据输出。但是不同的浏览器会设置不同的buffer大 小。为了保险期间,可以发送4096个空格,因为目前比较流行的浏览器的buffer还没有超过4k(一个内页大小)。

目录
相关文章
|
存储 缓存 安全
PHP的passthru() 函数:执行一个命令,并将输出直接发送到输出缓冲区,缓冲区是干什么的?为什么要发送到缓冲区?
PHP的passthru() 函数:执行一个命令,并将输出直接发送到输出缓冲区,缓冲区是干什么的?为什么要发送到缓冲区?
497 0
|
缓存 PHP
php缓冲区与header函数之间的秘密
我们在实际的开发中,是否听说过在header之前不能有任何的实际输出。甚至有的认为header函数必须写在代码的最前面。可是你是否试验过header函数之前输出东西?下来让我们更深层次的了解一下 测试header之前有输出
921 0
|
5天前
|
关系型数据库 MySQL PHP
PHP和Mysql前后端交互效果实现
本文介绍了使用PHP连接MySQL数据库的基本函数及其实现案例。内容涵盖数据库连接、选择数据库、执行查询、获取结果等常用操作,并通过用户登录和修改密码的功能实例,展示了PHP与MySQL的交互过程及代码实现。
34 0
PHP和Mysql前后端交互效果实现
|
5月前
|
关系型数据库 MySQL Linux
查看Linux、Apache、MySQL、PHP版本的技巧
以上就是查看Linux、Apache、MySQL、PHP版本信息的方法。希望这些信息能帮助你更好地理解和使用你的LAMP技术栈。
280 17
|
10月前
|
前端开发 关系型数据库 MySQL
PHP与MySQL动态网站开发实战指南####
【10月更文挑战第21天】 本文将深入浅出地探讨如何使用PHP与MySQL构建一个动态网站,从环境搭建到项目部署,全程实战演示。无论你是编程新手还是希望巩固Web开发技能的老手,都能在这篇文章中找到实用的技巧和启发。我们将一起探索如何通过PHP处理用户请求,利用MySQL存储数据,并最终呈现动态内容给用户,打造属于自己的在线平台。 ####
406 0
|
6月前
|
关系型数据库 MySQL PHP
源码编译安装LAMP(HTTP服务,MYSQL ,PHP,以及bbs论坛)
通过以上步骤,你可以成功地在一台Linux服务器上从源码编译并安装LAMP环境,并配置一个BBS论坛(Discuz!)。这些步骤涵盖了从安装依赖、下载源代码、配置编译到安装完成的所有细节。每个命令的解释确保了过程的透明度,使即使是非专业人士也能够理解整个流程。
143 18
|
7月前
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
313 25
|
10月前
|
安全 关系型数据库 MySQL
PHP与MySQL动态网站开发实战指南####
——深入探索LAMP栈下的高效数据交互与处理技巧 ####
|
9月前
|
存储 关系型数据库 MySQL
PHP与MySQL动态网站开发:从基础到实践####
本文将深入探讨PHP与MySQL的结合使用,展示如何构建一个动态网站。通过一系列实例和代码片段,我们将逐步了解数据库连接、数据操作、用户输入处理及安全防护等关键技术点。无论您是初学者还是有经验的开发者,都能从中获益匪浅。 ####
|
10月前
|
关系型数据库 MySQL PHP
PHP与MySQL动态网站开发实战指南####
深入探索PHP与MySQL的协同工作机制,本文旨在通过一系列实战案例,揭示构建高效、稳定且用户友好的动态网站的秘诀。从环境搭建到数据交互,再到最佳实践分享,本文为开发者提供了一条清晰的学习路径,助力其在LAMP(Linux, Apache, MySQL, PHP/Perl/Python)栈上实现技术飞跃。 ####