诡异的php 输出缓冲
我的本地环境 windows + apche + php5.2
今天,碰到一个诡异的问题,以前认为 php 脚本中调用 heade()函数之前不能有任何的如 echo,print ,print_r,var_dump等输出,否则的话就会报错。
但是,
1 2 3 4 5 | <?php header( 'Expires: Mon, 26 Jul 1998 05:00:00 GMT' ); echo "Expires: Mon, 26 Jul 1998 05:00:00 ;" ; header( 'Expires: Mon, 26 Jul 1978 05:00:00 GMT' ); |
想上面这样,浏览器访问,执行脚本,没有报错。(本以为汇报这样的错误:Warning: Cannot modify header information - headers already sent by)
此事何解:???
方法:
打开浏览器的调试控制台,发现 HTTP response header 中的Exipres 为 1978,顿时明白了。
联想到php 的输出缓冲的问题,在php 的配置文件中,有这么一段,看最后一句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ; Output buffering is a mechanism for controlling how much output data ; (excluding headers and cookies) PHP should keep internally before pushing that ; data to the client. If your application's output exceeds this setting, PHP ; will send that data in chunks of roughly the size you specify. ; Turning on this setting and managing its maximum buffer size can yield some ; interesting side-effects depending on your application and web server. ; You may be able to send headers and cookies after you've already sent output ; through print or echo . You also may see performance benefits if your server is ; emitting less packets due to buffered output versus PHP streaming the output ; as it gets it. On production servers, 4096 bytes is a good setting for performance ; reasons. ; Note: Output buffering can also be controlled via Output Buffering Control ; functions. ; Possible Values: ; On = Enabled and buffer is unlimited. (Use with caution) ; Off = Disabled ; Integer = Enables the buffer and sets its maximum size in bytes. ; Note: This directive is hardcoded to Off for the CLI SAPI ; Default Value: Off ; Development Value: 4096 ; Production Value: 4096 ; http: //php.net/output-bufferingoutput_buffering = 4096 |
4K字节的缓冲,这意味着 前面的这两个输出
1 2 | header( 'Expires: Mon, 26 Jul 1998 05:00:00 GMT' ); echo "Expires: Mon, 26 Jul 1998 05:00:00 ;" ; |
还缓冲在服务器中(我的是apache服务器,nginx服务器有是怎么样子呢,这个还不知道。。。),还没有通过http输出到浏览器,因此,后面的
1 | header( 'Expires: Mon, 26 Jul 1978 05:00:00 GMT' );这个输出呢,就把缓冲区中的 响应头修改为了 1978。<br><br>另外:<br> 1、如果输出达到 4096(4k)字节时,服务器会立即将缓冲区中的内容 flush 出来,即立即输出给浏览器。<br> 2、关于缓冲区处理的一些列函数,php提供了 ob_flush(), ob_get_contents()等一系列函数<br><br>还有一点:当我们不确定 缓冲区中的内容是否已经有输出,那怎么办呢?<br>php 内置的函数 headers_sent() 可以用来判断,一些框架 如cakephp中就是这个来检查的!! |
if (!headers_sent()) {
header( 'Expires: Mon, 26 Jul 1978 05:00:00 GMT' );
}
这样就可以了,就确保不会报这样子的错 Warning: Cannot modify header information - headers already sent by
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现