关于php的output controll参考文档:
http://gywbd.github.io/posts/2015/1/php-output-buffer-in-deep.html
http://www.cnblogs.com/liuzhang/p/4161213.html
众所周知,调用header()函数之前不能有任何输出到浏览器,否则会报错。
如何复现这种情况:
1、php.ini设置output_buffering OFF
2、测试代码:
echo 2; header("HTTP/1.1 503 Service Unavailable");
3、这样程序就会报错:
Warning: Cannot modify header information - headers already sent by
如何修复这种错误:
方法1:
php.ini中output_buffering 4096设置一个4K的大小,这样程序的echo就会一直缓存到php(或者缓存到web server ?)直到缓存大小为4K或者调用ob_系列函数才会输出。
这也是下面代码直到sleep 2s后才能显示所有结果的原因:
echo 2; sleep(2); echo 3;
方法2:
方法1中output_buffering 4096表示默认php程序开启输出(针对echo printf等函数)缓存(效果等同于ob_start()函数),此时调用ob_get_level()得到的结果是1。
所以可以调用关闭缓存函数来关闭输出缓存
ob_end_clean()或者ob_get_clean()
ob_end_clean(); echo 2; header("HTTP/1.1 503 Service Unavailable");
这样就会报错了。
但是如下代码也并不会立即输出结果:
ob_get_clean(); echo 2; sleep(2); echo 3;
原因应该是ob_函数只关闭了php的输出缓存,而echo的东西依旧存在web server里面被缓存着,也只有等待程序完毕web server才把输出完全发送给浏览器。
如果想要程序echo一个东西浏览器就显示一个,可以如下操作:
echo str_pad(‘‘,4096)."\n"; //这一行很重要,强制使缓冲溢出,4096等于output_buffering 的值 echo 1; ob_flush(); flush(); sleep(2); echo 2;
//@todo 未完成,需要重新理一理,还未完全搞懂。flush和ob系列函数有些是控制php缓存的,有些是控制web server缓存的。
时间: 2024-12-16 01:44:28