php setcookie 报错怎么办
php setcookie报错是因为setcookie()之前有输出,其解决办法就是将输出的echo的数据和header头的cookie一起发出去即可。
本文操作环境:windows7系统、PHP7.1版,DELL G3电脑
php setcookie 报错怎么办?
PHP setcookie()之前不能有任何输出
PHP的setcookie函数,手册里是这么写的:
setcookie() defines a cookie to be sent along with the rest of the HTTP headers. Like other headers, cookies must be sent before any output from your script (this is a protocol restriction). This requires that you place calls to this function prior to any output, including <html> and <head> tags as well as any whitespace.
大致意思是在setcookie之前不能有东西输出到客户端浏览器,否则会报错。但是经测试发现,并没有报错。继续翻看手册:
You can use output buffering to send output prior to the call of this function, with the overhead of all of your output to the browser being buffered in the server until you send it. You can do this by calling ob_start() and ob_end_flush() in your script, or setting the output_buffering configuration directive on in your php.ini or server configuration files.
于是我修改了php.ini(PHP版本5.4)的output_buffering为0,即关闭缓冲区。(PHP5.3版本以下是关闭的,5.3之后是默认开启,值为4096)
意思是如果在输出cookie之前,设置了ob_start和ob_end_flush来输出缓冲区,则不会报错。那么,为什么cookie和缓冲区的数据一起返回就没有报错呢?应该是因为:缓冲区的数据将整理成一个完整的HTTP包发出去。
我们可以看一下报错信息:
echo "i am going to setcookie"; var_dump(setcookie('buhehe', 'asdasdasdasdad')); print_r($_COOKIE);
“请不要修改header信息,因为header已经发送过了。”很明显,没有使用缓冲区输出,则header先一步返回到浏览器了,然后再进行setcookie发送header头信息的时候,就报错啦——不符合HTTP协议的规范。因为HTTP协议规定header应该在body之前输出。
我把代码修改了一下,把将输出的echo的数据和header头的cookie一起发出去。
ob_start(); echo "i am going to setcookie"; var_dump(setcookie('buhehe', 'asdasdasdasdad')); ob_end_flush(); print_r($_COOKIE);
结果如下:
当你设置output_buffering为0也就是在php.ini关闭缓冲区的时候,就需要手动ob_start来开启缓冲区了。
为什么有些开发者测试的时候,发现setcookie之前echo了信息也没有报错呢?
因为当前大部分的PHP应用都是5.3+ 的,有些甚至用上了7。PHP5.3+版本中,因为默认开启了缓冲区,并且默认size为4096,所以在setcookie之前echo的数据,以及cookie的header头信息,都会在缓冲区被封装成HTTP包,发给客户端啦~所以也就不会产生上图中的报错信息(请勿修改HTTP的header头信息)啦~~
推荐学习:《PHP视频教程》