关于BOM头

要命的BOM头让我吃了两次亏,每次都是莫名奇妙地花了1,2天才找出问题。
第一次是:写ZF的errorControler设置404返回值的时候报错:
Cannot modify header information - headers already sent
检查了那个有名的ZF最后一个结束符不写的问题和setRawHeader的代码,都找不出症结所在,后来发现是BOM头捣鬼。
今天又碰到这个问题,导入系统一个excel文件,老有错,仔细检查是第一行含有bom头,所以数据老是读错,害我花了半天的时间找问题。

在Windows下用记事本之类的程序将文本文件保存为UTF-8格式时,记事本会在文件头前面加上几个不可见的字符(EF BB BF),就是所谓的BOM(Byte order Mark)。

php4/5会视BOM为一般字符输出(这是一个不可见字符),因此会出现这个header already sent的问题。应该说这是一个php的bug(22108, 42312),可喜的是,php6宣传已经没有这个问题,而在php4/5下,有两个方法可以解决这一问题:
方法一,可以在保存文件的时候设置不使用BOM头格式的UTF8文件。
dreamweaver设置如下:

UltraEdit可以设置(Configuration-> File Handling -> Save -> Write UTF-8 BOM header),
也可以直接修改C:\Windows\UEdit32.ini,增加以下两行设置
Write UTF-8 BOM=0
Write UTF-8 BOM NF=0

此外HTML代码中的codepage及charset也必须要设定,以保证编码方式正确。

方法二,以上方式可以解决自己写的代码,却不能解决用户上传的文件。这种情况下,需要在服务器端判断文件头,并截取相应的三个字符(0xEF 0xBB 0xBF),以下代码是FCKeditor的一段代码,由于考虑到可能要处理的文件较大,所以将传值函数改成传递引用:
//strip UTF8 BOM if any
function StripUtf8Bom( &$data ){
  if ( substr( $data, 0, 3 ) == "\xEF\xBB\xBF" ){
   $data=substr_replace( $data, '', 0, 3 ) ;
   return TRUE;
  }
  return FALSE;
}

关于为何能提高性能,见风雪之隅的博客介绍的php传递引用的实现


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值