在讨论区更改 UseBB 页面编码格式导致乱码

今天偶然从 Internet Explorer 中打开论坛,发现字体很难看。而如果不使用 GB2312 编码而是 UTF-8 编码格式的话,在 IE 中查看的效果与 Firefox 和 Chrome 是没有区别的。都怪我一直不怎么用 IE,在当初设置 UseBB 的中文页面编码时没有发现这个问题。

请看文章结尾的更新

所以决定将 UseBB 的中文页面语言编码格式改为 UTF-8。但是这会导致比较严重的问题。那就是,使用 GB2312 编码时编辑保存的页面在改为 UTF-8 页面字符编码格式后会显示为乱码。此时,如果不使用浏览器的页面编码自动选择而是手动选择为 GB2312 格式,则原来是乱码的部分变成正常,而原来正常的文字则又变成乱码。

没办法,最终我还是选择改为使用 UTF-8 格式。而且花了几个小时将一些重要的帖子重新编辑,使之变得正常。我认为存在一种程序能够自动完成这项任务,可惜因为我对 mysql 的了解甚少,只好这么蛮干了。希望懂行的朋友能够提供解决方案。

问题描述:

MySql 数据库存储编码格式为 latin1,当网页页面 CharSet 设置为 GB2312 时发表帖子,再将网页页面 CharSet 设置为 UTF-8 时,该帖子页面显示乱码。此时,如果将页面 CharSet 手工设置为 GB2312 则可以正常显示文字。

通过在页面 CharSet 设置为 UTF-8 时重新编辑保存该帖子,则在 CharSet 为 UTF-8 时可以正常显示。

现在需要找到一个方法自动对数据库中的部分帖子(原来页面 CharSet 为 GB2312 时发表的那一部分帖子)进行转换,使之能够在 CharSet 为 UTF-8 时正常显示。

我的理解是,需要将上图中红线框出来的部分转换成未框出部分那种形式。

针对 UseBB 的中文汉化文件到底该设置网页页面使用何种编码格式,曾经跟几个网友有较多讨论。几经变更,结果还是选择了一个错误的方向。都不知道以后该怎么处理这件事情了。

更新 2011-09-20

根据网友 KK 以及 newmewo 的分析与建议(评论1评论2),综合我一段时间以来的实践,现已基本确定了解决方案。有 2 种选择:

1、保持数据库编码不变,更改 HTML 页面编码格式为 UTF-8。我比较倾向于这种方法。

  • 好处:不需要更改 UseBB 的源代码,仅需要在翻译的语言文件中指定编码格式;
  • 坏处:数据库中看到的是 &#nnnnn; 的格式显示特定的字符。nnnnn 代表该字符的十进制 Unicode 代码。(如上图)

2、将数据库校对字符集改为 utf8,同时更改 HTML 页面编码格式为 UTF-8。

  • 好处:解决了 1 的坏处,在数据库中可以看到正常显示的汉字;
  • 坏处:需要修改 UseBB 源代码(可参考这里进行修改);并且,如果在修改前数据库中已有中文记录,需要做转码处理。

目前沿用 1 的方法。等有空了看看能不能写个自动转换的小程序来进行 2 中提到的转码。©

本文发表于水景一页。永久链接:<http://cnzhx.net/blog/change-usebb-html-charset/>。转载请保留此信息及相应链接。

11 条关于 “在讨论区更改 UseBB 页面编码格式导致乱码” 的评论

  1. 有二个方法:
    1、将原mysql数据导出后经过转换编码后再导入,如:mysqldump+iconv命令,具体GG一下“mysql 编码转换”;
    2、在PHP页面取到数据后再进行编码转换,如mb_convert_encoding($string,’utf-8′,’gb2312′);
    另外可尝试在显示页上强制指定编码,第一行上加入:header(“Content-type:text/html;charset=utf-8”);

    • 非常感谢!
      可是现在的情况是有一大部分帖子(重要的)是正确的,不需要转换。
      这样的话,采取你说的方法会不会影响到它们?
      而且,数据库本身还是以 latin1 存储的,问题出现在 PHP 到 mysql 这个环节。请看看我新上的图。

  2. 我没使用过UseBB,并没有切实的解决方法。但说到对多语言的支持UTF-8肯定比GB2312强。所以建议你还是选择UTF-8,且须保证所有步骤一致,包括录入、存储(数据库格式)及输出均用一个编码。

    在做导出/导入转换时mysql会分析字符类型的,所以不会影响那些不须转换的字符串,但为求稳妥,转换前做好备份也是必要的。

    图中所示,你的理解是正确的,数据转换完了就是一致的数据类型了。非红线框中的字符“&#…”是被程序格式化过了的存储格式,大概是UseBB里的操作吧。不用担心,浏览器输出时会自行转换。

    • 我这个只能在录入的时候使用 UTF-8,存储的时候使用 latin1,输出是 UTF-8。所以我想做的其实可以描述为,使用 PHP(或类似的方法)通过 UseBB 的方法取出那些数据(可在 GB2312 编码下显示为正常的汉字),将这些数据转换为 UTF-8 编码下显示正常的汉字,然后再通过 UseBB 使用的方法将其存入数据库。其它的东西保持不变。
      你提供的方法似乎是为了将 MySQL 数据库的存储编码(Collation)转换为别的格式。

  3. 是二者兼顾,参考这篇文章:http://www.21andy.com/blog/20060514/297.html
    其中的“附:旧数据升级办法”这段,文中的第二步就是转换现有数据的类型。

    当然按你上面的思路也是可以的,如果你对PHP熟悉的话。写个小程序把需转换的数据取出来加工好后再存回去。

    方法很多种,就看哪种适合你。

    • 谢谢你的热心帮助!
      前面我根据你的提示试过了,也许还是有什么地方做得不对,所以结果没变化。
      这次你提供的这篇文章中的附注的方法似乎需要在 Linux 系统下运行。我目前没有可用的 Linux 系统,主机又不支持 SSH,回头再试试看。
      太感谢你了!我对这个实在是没有头绪。

  4. 中文, 建议沿用 utf8编码, 至于数据库编码当中的问题,主要是跟mysql 版本有关系, 在4.1以前的版本中是不区分数据库编码的。更准确的说是只适用mysql启动时候指定的编码, 到4.1 以及以后的版本,每个库,每个表都可以有不同的编码。就造成了这个问。
    根本点找到了就知道如何打补丁了。
    安装的时候。 应该判断mysql版本,为简便起见可以让支持utf8编码的数据库用utf8编码, 之后是内码选择, 应该用utf8兼容性好点。
    之后在mysql 以及 mysqli 操作里。 增加关于编码的内容。这样就可以确保最终输出结果不至于乱码。

    • 谢谢你提供的思路!
      现在还有个问题就是,因为不想改动官方发布的 UseBB 源代码,所以迟迟未做说明。
      只要改变源代码就很容易解决这个问题。
      你说的安装的时候设置数据库的问题,也需要修改安装源代码。
      我已按照你还有前面的提示修改文章内容。
      再次感谢!
      P.S. 你的网站是不是数据库连接错误了?

      • 昨天误操作本来想重新安装usebb 数据库,结果清除了其他数据库。
        早上一直在维护数据库,所以出现数据库连接问题。

        说说我的处理办法。 中文部分还是utf8编码,几乎所有页面都引用 sources/common.php
        所以,我修改了这个文件, 大约在328行左右。找到这部分代码
        $db->connect($dbs);
        这代码是用来连接数据库的。
        我增加了这个代码。
        @ $db->query(“SET NAMES ‘utf8′”);
        如果不强制阻止错误,在执行安装程序的时候会抛出异常。
        @ $db->query(“/*!40100 SET NAMES ‘utf8’ */”);

        我是个懒惰的人。 呵呵。

        所以总结, 安装usebb 的方法, 首先进入数据库管理。 建立准备安装的数据库, 并设置 连接校验 utf8 , 默认数据库编码 utf8.
        同时修改 sources/common.php 文件,在 大约328行位置找到
        $db->connect($dbs);
        并在下面一行加入
        @ $db->query(“/*!40100 SET NAMES ‘utf8’ */”);
        然后建立config.php 文件, 可以从文件包中复制。并设置 web php执行者身份拥有修改权限。
        剩下的就是执行安装了。

雁过留声,人过留名

您的电子邮箱地址不会被公开。 必填项已用 * 标注

特别提示:与当前文章主题无关的讨论相关但需要较多讨论求助信息请发布到水景一页讨论区的相应版块,谢谢您的理解与合作!请参考本站互助指南
您可以在评论中使用如下的 HTML 标记来辅助表达: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>