注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

@fc_lamp

关注Web应用解决方案MySql/PHP/Python一盏名为"飞川"的灯~

 
 
 

日志

 
 

关于setcookie -中的Warning: Cannot modify header informay sent by问题  

2015-01-08 17:19:07|  分类: Web技术-应用研究 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
PHP官网上已经说的很清楚了http://php.net/manual/zh/function.setcookie.php:

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.

意思就是说:像其它HTTP响应头一样,发送COOKIE头域之前也是不能有任何字符输出的,当然包含了空白行。
不过,对于新手来说这个问题还是不容易解决的。
当你仔细看过,每个文件后仍然找不到哪里输出字符,那可能就是UTF-8 BOM作怪了(也可能是其它编码问题)(什么是UTF-8 BOM请GOOGLE吧)。

问题还原:
今天我们来演示一下,这一问题。
首先,我们以editplus新建一个文件,并保存为:
关于setcookie -中的Warning: Cannot modify header informay sent by问题 - fc_lamp - @fc_lamp
 
coding那里,我们保存为了UTF-8+BOM。
ok,我们写入如下代码:

<?php
error_reporting(E_ALL);
setcookie('test','test');

然后我们访问:http://localhost/Noname2.php ,(如果你的服务器没有特别的设置,我是说:关闭缓冲之类的,当然多数人的都一样)。然而页面并没如我们期忘的那像报错,而且如果你用工具查看COOKIE,test也设置成功了。
关于setcookie -中的Warning: Cannot modify header informay sent by问题 - fc_lamp - @fc_lamp
 

但是为何PHP没有报错呐??这因为服务器缓冲的原因,空白字符正常的写在本次HTTP响应body里,和响应头中COOKIE一起发送给客户端的(关于这个问题参看:ob_flush、flush)。
那么如何还原这一问题呐?在输出字符很少很少情况下,即小于服务器缓冲值,我们使用ob_*系列函数来实现(如果你在有些项目中使用了CMS或者PHP框架之类,在输出空白字符前输出的字节大小已超过了服务器缓冲值,所以就不需要使用ob_flush了)。源文:http://fc-lamp.blog.163.com/blog/static/17456668720150845046630/

<?php
error_reporting(E_ALL);
ob_flush();
setcookie('test','test');

我们再运行,就可看到报错了:

Warning: Cannot modify header information - headers already sent by 。。。。。。

这是因为,ob_flush强行先让服务器输出它缓冲区里的内容到客户端(浏览器)。而后面的COOKIE头域已法在本次响应头中设置,所以报一个warning错!

解决问题:
如果发现是以上问题,最简单的就是新建一个文件,重新选定编码就OK了。
ps 附上python查找代码:

#coding:utf-8
'''
@author:fc_lamp
@blog:http://fc-lamp.blog.163.com/
@sourc:http://fc-lamp.blog.163.com/blog/static/1745666872011626510810/
'''
import os
import time
def findBom(path):
global i
if not os.path.isdir(path) and not os.path.isfile(path):
return False
if os.path.isfile(path):
i+=1
fh=open(path,'r')


#while True:
# line=fh.readline()
# if not line:
# break

# print(line.decode('utf-8'))

line=fh.readline(3) #前三个字符
if '\xef\xbb\xbf'==line: #表示BOM
print '%s<------------>Has BOM'%(path)
else:
print path

#lines =[]
#lines.append(line)
#print(lines)

fh.close()

elif os.path.isdir(path):
for x in os.listdir(path):
findBom(os.path.join(path,x))






'''
DEMON
'''


fPath = 'F:/testbom'
s = time.time()

i=0
findBom(fPath)

c = time.time()-s

print(u'运行耗时: %0.2f'%(c))
print(u'处理文件数:%s'%(i))




  评论这张
 
阅读(214)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017