# PHP缓冲区
>PHP中有一个"输出缓冲区"层!首先要明确"输出缓冲区"是基于PHP5.4(以及以上版本),PHP中的OB层从5.4版开始就发生了很多变化,确切说是完全重写了,有些地方可能都不兼容PHP 5.3了。
## 什么是输出缓冲区?
PHP的输出流包含很多字节,通常都是程序员要PHP输出的文本,这些文本大多是echo语句或者printf()函数输出的。首先要明确,PHP的任何输出都会用到缓冲区,但是如果是用PHP编辑扩展,用到的函数(C函数)可能会直接输出写到SAPI缓冲区,而不红过OB层。
>[danger]"输出缓冲区层"不是惟一用于缓冲区输出的层,它实际上只是很多层中的一个。并且`输出缓冲区层`与使用的(web和cli)有关。不同的SAPI可能有不同的行为。
>[info]CLI的SAPI有点特殊。CLI会将INI配置中的output_buffer选项强制设置为0,这表示禁用默认PHP输出缓冲区。所以在CLI中,默认情况下你要输出的东西会直接传递到SAPI层,除非你手动调用ob_()类函数。并且在CLI中,implicit_flush的值也会被设置为1。
## 默认PHP输出缓冲区
如果你使用不同于CLI的SAPI,像PHP-FPM,你会用到下面三个跟缓冲区相关的INI配置选项:
- output_buffering
- implicit_flush
- output_handler
>[danger]不能在运行时使用ini_set()改这几个选项的值。这些选项的值会在PHP程序启动的时候,还没有运行任何脚本之前解析,所以也许在运行时可以使用ini_set()改变它们的值,但改变后的值并不会生效,一切都已经太迟了,因为输出缓冲区层已经启动并已激活。你只能通过编辑php.ini文件或者是在执行PHP程序的时候使用-d选项才能改变它们的值。
>[info]默认情况下,PHP发行版会在php.ini中把output_buffering设置为4096个字节。如果你不使用任何php.ini文件(或者也不会在启动PHP的时候使用-d选项),它的默认值将为0,这表示禁用输出缓冲区。如果你将它的值设置为“ON”,那么默认的输出缓冲区的大小将是16kb。你可能已经猜到了,在web应用环境中对输出的内容使用缓冲区对性能有好处。默认的4k的设置是一个合适的值,这意味着你可以先写入4096个ASCII字符,然后再跟下面的SAPI层通信。并且在web应用环境中,通过socket一个字节一个字节的传输消息的方式对性能并不好。更好的方式是把所有内容一次性传输给服务器,或者至少是一块一块地传输。层与层之间的数据交换的次数越少,性能越好。你应该总是保持输出缓冲区处于可用状态,PHP会负责在请求结束后把它们中的内容传输给终端用户,你不用做任何事情。
>[danger]implicit_flush已在前面谈论CLI的时候提到过。对于其他的SAPI,implicit_flush默认被设置为关闭(off),这是正确的设置,因为只要有新数据写入就刷新SAPI的做法很可能并非你所希望的。对于FastCGI协议,刷新操作(flushing)是每次写入后都发送一个FastCGI数组包(packet),如果发送数据包之前先把FastCGI的缓冲区写满会更好一些。如果你想手动刷新SAPI的缓冲区,使用PHP的flush()函数。如果你想写一次就刷新一次,你可以设置INI配置中的implicit_flush选项,或者调用一次ob_implicit_flush()函数。
>[success]output_handler是一个回调函数,它可以在缓冲区刷新之前修改缓冲区中的内容。PHP的扩展提供了很>[success]多回调函数(用户也可以自己编写回调函数)。
- ob_gzhandler : 使用ext/zlib压缩输出
- mb_output_handler : 使用ext/mbstring转换字符编码
- ob_iconv_handler : 使用ext/iconv转换字符编码
- ob_tidyhandler : 使用ext/tidy整理输出的HTML文本
- ob_[inflate/deflate]_handler : 使用ext/http压缩输出
- ob_etaghandler : 使用ext/http自动生成HTTP的Etag
>[success]缓冲区中的内容会传递给你选择的回调函数(只能用一个)来执行内容转换的工作,所以如果你想获取PHP传输给web服务器以及用户的内容,你可以使用输出缓冲区回调。当前有一点也需要提一下,这里说的“输出”指的是消息头(headers)和消息体(body)。HTTP的消息头也是OB层的一部分。
- 前言
- PHP获取服务器信息
- PHP中的常用函数-新手必备知识
- 日期时间相关的函数
- 时区设置
- time函数
- strtotime 时间戳
- date函数
- mktime函数
- 联合使用 date() 和 mktime()
- PHP数据类型相关的函数
- PHP数组相关的函数
- array函数
- 数组的排序
- sort()和rsort()函数
- asort()和arsort()函数
- ksort()和krsort()函数
- array_multisort()函数
- array_reverse函数
- 数组的遍历
- 数组中新增和删除元素
- 数组头部插入和删除元素
- 数组尾部插入和删除元素
- 删除数组中重复的元素
- 删除数组中指定的元素
- 数组的合并
- 随机/打乱已知数组
- range函数
- 数组去除重复
- PHP常用功能函数
- URL地址处理函数
- post/get请求
- PHP字符串相关的函数
- PHP文件系统
- PHP正则表达式
- 正则表达式语法规则
- POSIX扩展的正则表达式函数
- 查找字串函数
- 替换字符串函数
- Perl兼容的正则表达式函数
- PHP中类的应用
- 中文编码
- 关于stdClass
- 变量相关函数
- unset
- PHP数值相关的函数
- 数值取整
- 开发工具与开发环境使用技巧
- sublime
- 常用插件
- Atom
- 常用插件
- 常见问题
- Visual Studio Code
- vscode常用插件
- 编程推荐字体
- MAC下开发常识
- MAC下的常用设置
- MAC下的常用开发工具
- MAC下XAMMP的常见问题
- Apache配置基础
- PhpStrom
- php中的常见问题
- 文件上传相关问题
- API接口中常见问题
- 关于缓冲区问题
- PHP中注意事项
- 条件判断
- PHP文件管理模块
- 文件管理源码
- 文件管理的常用函数
- 文件管理中文乱码处理
- 自定义功能函数
- 文件下载
- PHP常用头信息定义汇总
- 常见PHP网页木马
- 加密算法
- 1. Base58可逆加密
- 2. AES加密/解密
- mysql数据库操作
- 命令行操作Mysql常用令行-查询
- 命令行操作Mysql常用令行-操作
- Mysql使用中的技巧
- 在线数据库管理中常用命令
- sql show命令
- mysql数据库的备份与恢复
- 二进制日志介绍
- 二进制日志常用命令
- ThinkPHP
- 数据迁移
- 常见问题
- 验证码问题
- API接口中的异常处理
- API接口安全
- 解决跨域问题
- 自定义实用功能函数