PHP中UTF-8的困扰,还有可恶的BOM..

序言:
前些日子,公司发邮件周刊,部分使用Windows English OS 的人反映,他们Outlook收到的是乱码,才意识到自己使用的是GB2312编码,而非国际ISO标准的UTF-8,马上改进,用Microsoft OS 自带的Notepad 直接另存为UTF-8编码,然后PHPMailer 测试发送给自己! 我靠,NND,什么东西,超级乱码,以为自己在PHPMailer里的编码设置错了,立刻检查!发现没错,多次更改测试,还是不可以! 怀疑编辑器有问题,立刻更换更强悍的UltraEdit,果然, 是Notepad另存为的时候,自动生成了BOM码在里面,我靠………. …………..

今天,在喜悦村(www.phpx.com)闲逛,看到一位仁兄的帖子,谈到了PHP中UTF-8的问题,哈,正好拿来复习复习,多谢这位仁兄了啊!以下是部分内容!


导言:

  • 什么是UTF-8
  • UNICODE,GBK,UTF-8区别
  • 什么是BOM
  • 关于UTF-8
    UTF-8是unicode编码的扩展(也可以说是子集:Unicode Translation Format),由Ken Thompson于 1992年创建,只要将某个字符的unicode编码一一插入相应的空位(刚好有16个空位)就可以成为一个UTF-8编码! 详情见(http://hi.baidu.com/itezone/blog/item/8d9ca35200c18b0c0df3e336.html)

    关于 BOM (浏览器对象模型(Brower Object Model))
    这里有,我不敖述了!http://baike.baidu.com/view/126558.htm

    UNICODE,GBK,UTF-8区别
    http://www.phpchina.com/42113/viewspace_16547.html
    言规正传
    1、编辑器:
    不要使用任何微软的编辑器,什么Frontpage,Web Designer,记事本,写字板什么的,能丢的全部丢开,因为这些编辑器会在你的UTF-8文档前面产生BOM,关于BOM的具体说明,可以在 这里 找到,当初我直接拿记事本转UTF-8覆盖原文件,造成………….,至今记忆犹新。
    2、MySQL数据库:
    注意建库,建表,建字段(注意有三处)的时候,都要选用utf8_general_ci的整理格式(Collation),在PHP使用mysql_connect()函数连接数据之后,需要加上一句:
    mysql_query(‘set names “utf8″‘);
    3、PHP:
    使用mbstring库,不要使用iconv库。
    使用preg而不要使用ereg来处理字符。
    使用htmlentities()函数,html_entity_decode()函数的时候要带上第三个参数:

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <?php
    $str = "<a href='test'>中文</a>";
    echo htmlentities($str,ENT_COMPAT,"UTF-8"); //显示(源代码里面) <a href='test'>涓枃</a>
    echo html_entity_decode(htmlentities($str,ENT_COMPAT,"UTF-8"),ENT_COMPAT,"UTF-8"); // 显示(源代码里面) <a href='test'>中文</a>
    ?>

    这里再给出一个匹配UTF-8中文字符的正则表达式:

    <meta http-equiv="Content-Type" Content="text/html; charset=utf-8">
    <?php
    $word = "中文";
    if (preg_match("/^([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){1}/",$word) == true || preg_match("/([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){1}$/",$word) == true || preg_match("/([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){2,}/",$word) == true)
    {
    echo "很好,这是一个UTF-8编码的汉字";
    }
    else
    {
    echo "抱歉,这不是一个UTF-8编码的汉字";
    }
    ?>

    4、HTML:在标签对里面加上

    <meta http-equiv="Content-Type" Content="text/html;charset=utf-8" />

    5、JS:JS的问题比较复杂,如果直接将文件存为UTF-8的编码,那么当用户在直接用浏览器访问这个页面的时候(也许某些程序员会这么做),浏览器可能会使用其它的编码去读取这个文件而造成其中的UTF-8中文乱码,当然,这并不会影响到程序的运行。在加载JS的时候,可以说明一下载入JS的编码,当然,如果已经在HTML头里面声明了编码,这里就不是必须的了:

    JS要注意的另一个问题是他的escape()函数,在ECMAScript v3中,escape( ) 会被剔除,建议使用encodeURI( )和encodeURIComponent( )。这可以帮助你远离escape()函数引起的乱码问题。
    6、CSS:在CSS文件的头部加上这行代码:
    @charset “UTF-8″;

    7、URL:为了让URL变得更为友好,许多PHP程序员喜欢让URL显示文字而不是URL编码,目前较为合理的解决方案是将GET方法发送的数据转为GBK编码,然后再接受这些数据,如果你希望使用UTF-8直接友好的GET数据,你会在使用PHP的$_GET数组时遇到一些问题。
    8、Email:使用UTF-8编码的字符发送邮件,也是一件让人头疼的事情,理想的方法是将编码转变为GBK,然后再发送。
    9、Ajax:使用POST的方式发送数据,不要使用GET的方式,不然无法成功发送部分UTF-8中文字符。

    随机日志

    发表评论

    4 Comments.

    1. 断枝残蓝

      没有看懂你那是怎么匹配UTF-8中文的,前段时间偶JAVA里也遇见乱码问题
      俺同学的一个波导什么型号的手机,看小说的时候没有乱码,很一致,都是小方块!
      import java.util.regex.Matcher;
      import java.util.regex.Pattern;

      public class FindChinese
      {
      public static void main(String[] args)
      {
      String f = “欢迎welcome to光临 wmdly,纯音乐部落,www.chunmusic.cn,谢谢!”;
      Pattern p = Pattern.compile(“[\\u4E00-\\u9FFF]+”);
      Matcher matcher = p.matcher(f);

      StringBuffer sb = new StringBuffer();
      while (matcher.find())
      {
      sb.append(matcher.group());
      }
      System.out.println(sb);
      }
      }
      ==================================
      Pattern p = Pattern.compile(“[\\u4E00-\\u9FFF]+”);
      这个貌似也能匹配中文,不晓得和中文UTF-8匹配有什么区别。
      ==================================

      国际化问题确实有很多让人郁闷的地方
      不过用UTF-8,再加上资源文件,貌似什么问题都没有哦
      比如
      把中文弄成这个样子\u9648\u9a70\u554a\uff1f\u8fd8\u597d\u554a\uff1f

      o(∩_∩)o…哈哈^_^鲁班门前刷大斧头了哦啊哈…………

    2. 哈,JAVA 没学过,大体看了下,你这个是匹配中文的吧! 呵呵, \\u4E00-\\u9FFF 是中文字符 在unicode编码中编码中的 区间 啊! 哈,你太谦虚了,会发胖的!

    3. 哈,这里说的很详细,我也是摸石头过河啊, 嘿嘿!

    4. PHP里面也可以这样匹配中文的啊

    Leave a Reply



    [ Ctrl + Enter ]

    *
    To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
    Click to hear an audio file of the anti-spam word

    CNXCT小组的博客 is Stephen Fry proof thanks to caching by WP Super Cache