DIARIO DE CHINOS 华侨快报(国际刊号 ISSN 2530-1349) 新手帮助

西班牙华人网-华侨快报

电脑爱好电脑爱好
关注: 0贴子:195 排名: 56 
0 回复贴,1331 次查看
<返回列表

Discuz! 从 GBK 转换 UTF-8 编码全过程

网友
网友  发表于 2017-7-27 19:57:51
在 Discuz! 诞生之时,国内网站清一色以 GBK 编码为主流,很多老站长都选择了以在当时很成熟的 GBK 编码来建站。如今过了十几个年头,Unicode 已经成功统治了世界,如何把 Discuz! 从 GBK 转换到 UTF-8 成了困扰很多老论坛的难题。7 c+ m, J7 C( p; L3 \

$ L- g8 ^$ y' f6 H5 |; z/ O5 r$ GSteamCN 论坛如今已经拥有十三年的历史,经历了 dvbbs、Discuz!、Discuz! X 三个阶段,是国内为数不多能完好保存十多年前附件和图片的论坛。今天在短短两小时的维护时间内,SteamCN 论坛成功从 GBK 编码完美转换到了 UTF-8(utf8mb4,支持 emoji &#128536;)。本文将记录转换所用的工具、脚本以及常见的坑,以供广大 Discuz! 站长参考。
2 ]) i" d0 `7 u1 l" Y) B( a
9 e  m8 Q. d* y2 ?7 N7 c
本次转换工作得到了 DxGit Forker 群内 Coxxsgreenrock[微凡] 的帮助,非常感谢二位的指导!
$ C7 q9 T0 _! `' w: Q9 ^1 x

! ^) n- |2 I3 h/ F8 Z# _0 L) |  P1. 准备工作( v7 b/ y- K$ ^+ o6 O
1 A7 J2 k4 ~& U/ b2 y
不同的网站都有自己的不同之处,请务必先在测试环境内演练转换过程,然后再应用到线上正式服务器。$ }; [$ ~+ N, Z9 g2 v& a
- f" a0 e6 y" M( J
1. 下载与自己当前 Discuz! 版本号相同的 UTF-8 安装包。本站为经过浅度定制的 Discuz! X3.3,以下教程以 Discuz! X3.3 为例来进行。如果你的网站经过深度定制,请人工将代码转换为 UTF-8 编码。) V! x8 _  ?1 I* r
2. 准备测试数据库。将当前线上版本数据库完整拷贝一份作为测试数据库,我们将先以该数据库进行一次演练。0 v, d- M7 c3 u- j3 P) A
3. 准备测试用 Web 服务器。将网站文件夹拷贝一份到测试 Web 服务器上。由于 data、uc_client/data、uc_server/data/avatar 这几个目录体积会比较大,可以忽略它们。
( b! c6 I1 R9 p) N. h4. 编辑测试环境中的 config/config_global.php、config/config_ucenter.php、uc_server/data/config.inc.php,将数据库配置为测试数据库,并关闭 Discuz! 的一切内存缓存功能。
" @+ z# ?7 E+ m5. 确认测试环境的网站可以正常运行。
2 Q* I# q& F& c5 ^7 e' N
/ n$ C3 m- ]' X5 G0 P  X# g2. 转换数据库
( w6 O- c: d4 o6 W
3 B3 ]$ e1 |* Y( S/ D' s' \我们需要人工手动使用这条语句对数据库中的每一个表进行转换:
# L; O* W2 }6 N+ F$ M/ B9 x& V% K5 G
  • ALTER TABLE `表名` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;1 V9 S/ k0 s& C, w) o
1 |; J; V& Y) B+ A
[color=rgb(87, 186, 232) !important]复制代码

) [2 t' s& L2 Y7 {; p3 d1 W$ y" L0 N
4 \4 Z; s+ `6 F! V8 s) P6 v+ C- a; R0 n% |; {  p. ^# C
务必将运行过的每一个语句记录下来中,方便最后在线上服务器部署。
) \5 R6 Z/ y. F
) g0 @  i* Z" T2 ?& s, E( G可能会遇到的问题:
1 z: L' o& m$ I- b  G) K
" Y1 F& ?) w" l- E" jQ: 为什么这里不提供预先编写好的 SQL 呢?
- t3 e7 u0 ]+ u' ?3 ^A: 因为每个网站的数据库差异很大,我们使用的 SQL 脚本(文末附件压缩包内 gbk-to-utf8mb4.sql)未必适合你的网站。这里需要人工对每一个数据表运行这个语句。
( L% ]4 m( I3 |& i0 m
) ]) f$ u7 d* b& r2 p2 Y' `) h5 E# IQ: 提示索引最大长度为 xxx,转换失败) }. ?7 b  o7 k( j% _  a
A: 调整索引涉及到的字段长度,保证不超过 xxx / 4。例如 pre_common_addon 这个表报错索引长度最大不能超过 1000,那么需要将 key 字段的类型从 varchar(255) 改为 varchar(200)。8 j: Z; G0 U5 B0 Q" F! y

1 ]6 S& ~. F9 a8 |, [Q: 提示用户名重复,转换失败) S" H' ]6 ^* ?& z! O; _, b
A: 这是由于一些字符在 gbk_chinese_ci 排序规则下认为是不同的,但是在 utf8mb4_unicode_ci 排序规则下认为是相等的。例如全角英文字母与半角英文字母,在 gbk_chinene_ci 下认为 A != A,但是在 utf8mb4_unicode_ci 下认为 A == A。这时需要编辑 unique 索引,改为普通索引,然后重新转换,再将索引改回 unique 类型,此时会具体指出哪个用户名重复,请记录其 UID。如果数据量比较大,可以自行编写 SQL 寻找重复项。
; E: w2 ^. B/ m5 `- @& v+ C对于重复的用户名,我们可以使用这个语句将该用户的用户名重置为 email:
' V4 q9 H4 u8 R' W2 W
  • UPDATE `表名` SET `username` = email WHERE `表名`.`uid` = 上面记录的用户UID;1 G( F9 S+ h5 v# c) p3 ^0 |
. p4 M4 K! ~2 m( g  \9 \
[color=rgb(87, 186, 232) !important]复制代码

" l- c$ [: i4 ^) ~1 g$ f$ e' ?4 a. Y! D: c- u. x* K+ ]" ~

6 p! N8 E% F# S5 |" x  ~3. 上传 UTF-8 版本代码
; o/ l' E  t( C0 I1 i9 D$ E. |* M" i4 J: `: ^
将准备阶段取得的 UTF-8 版本代码覆盖到测试服务器中(注意不要覆盖掉 config 文件)。2 m' ?$ R! j8 D- Z
编辑 config/config_global.php、config/config_ucenter.php、uc_server/data/config.inc.php,将其中 DBCHARSET 改为 utf8mb4,输出 CHARSET 改为 utf-8。, u! Y- e9 N. ~4 O2 X( U
到此先不要打开网站测试效果!2 H4 b7 \- l# U: v

1 V2 ~) t" H$ |6 T2 L4. 修复数据库
, Z1 C7 p$ L: f' l! N% K4 c% v: B& l4 o% J  v
由于 Discuz! 大量使用了 PHP 的 serialize 方法来序列化对象存入数据库,而 serialize 方法序列化出来的结果和编码是相关的,因此需要修复数据库中以前使用 GBK 编码序列化的结果,使其能在 UTF-8 编码下反序列化出来。
+ W" X# \! j( S. d( |/ X, U7 _
5 i" E, p0 D' N. D扩展阅读$ T& _( E2 C' x1 m( N- w. s
! e3 Y' Q1 y' R
下载文末附件“脚本与工具.zip”,解压出来得到 migrate_db.php(出处,略做修改),编辑该文件结尾的数据表列表,确认这些表和字段都是在你数据库存在的。这个列表未必完善,建议手动检查一遍所有数据表,补充可能漏掉的数据表和字段。第 29 行指定了单次处理的数据条数,如果你的数据库性能比较差,建议降低该值。! w3 @) j9 }7 Y% x% n

) m% J( h! D- c% H' H7 `将 migrate_db.php 上传到网站根目录,浏览器访问它,点击“Discuz! 序列化整理”开始修复。
$ F) L/ l1 _( t* a
8 j0 _3 ~6 ]1 L5 B# z5. 转换模板、插件编码: [0 E8 n( `) l

  m2 k( @! C- U2 G% E, W$ a人工将你所有使用的模板、插件的编码转换为 UTF-8。注意不要漏掉 XML 文件。
" P( B% O2 }' A6 Q如果你的模板、插件是从应用商店下载的,没有经过改动,建议登录后台进行卸载,在应用中心重新安装一遍。- C" Q8 N8 L; O: ]& ^+ R

; N$ M+ y4 D  g* x; C6. 转换日志编码( _! ?0 J# k5 ^" g& X, h

7 p5 c: l6 o% U# @" ~$ [/ O( BDiscuz! 将运行日志记录在了 data/logs 目录下,如果你在准备阶段没有将这个目录复制到测试环境,可以在最终部署时再进行。
! Z; ]' ^. n/ \& K1 \/ Z. X" ~将该目录下的每个文件的编码转换为 UTF-8,重新上传覆盖原文件即可。3 o4 g5 X/ a$ R$ C" x5 c$ a5 k
" Y" W7 m3 w3 Z, L% R' I0 W
7. 更新缓存
$ U+ j0 n& V0 y( G* y  T3 V1 j$ y7 z3 A3 s3 z9 C
登录后台,更新所有缓存(数据缓存、模板缓存、DIY模块分类缓存)。! W4 \% q5 |! v" x( c+ }! l: k) d9 n8 A

% X! i5 G% K+ f& n8. 检查问题# I' {: b  l- F0 n2 |; ~; F

& p6 r: U2 |* Z! A/ E* |至此基本转换完成,需要仔细检查有无其他问题,重点检查插件、模板等是否工作正常。0 k  P" x8 b# f0 u0 t. A

: e4 l. k  H& T5 F% m9. 在正式环境部署上线: f2 \) L9 z! E7 j) h: P

9 g- [$ {+ v2 \: G一定要先阅读下面的 FAQ 再决定开始部署。
% g3 @0 l$ P; E7 `+ Y# m7 N: f9 a3 ]) C7 T1 @9 N, n( S( z" f; R; U
将以上步骤在正式服务器上重新操作一遍。需要注意将 config 中的数据库改为正式数据库,内存缓存无需关闭,在第 7 步更新缓存时要把内存缓存清空。
' Z5 x5 J+ C; C& [3 `& l$ z' {' u
F.A.Q.& M6 ^! O2 l: i/ T/ b

% X% c9 Z2 n* r+ ?- s6 k8 hQ: 转换数据库后,登录验证问答无法通过
$ ?2 s3 `6 u# I" e. J3 @4 CA: Discuz! 登录验证问答的加密算法为“substr(md5($answer.md5($questionid))”,结果与所用编码相关。可以参考这里修改代码,强制使用 GBK 来编码答案。
# b" \" }, j7 v+ P5 Y" a7 g3 }" I( m" w% o- K5 R6 b: I
Q: 转换模板后打开网站依旧乱码
' _5 j) K8 }$ ]( [& RA: 请确认已经在后台更新缓存,如果依旧乱码,请 SSH 到服务器,运行 sync 命令。如果还不行,可以尝试修改乱码的模板(比如随便改一个字符),上传服务器,Discuz! 检测到文件变动后会重新刷新模板缓存,然后再将模板还原后上传。; W  y# a$ [+ O9 ?

" u6 J8 u& a$ ^Q: 站点统计内部分数据乱码3 ?8 E) W* M! }8 q" u) v; p6 H, J
A: 等到下一个更新时间数据刷新后就正常了+ C( Z. X- u, z; t) I! G  f. T
  B+ n; v* C. B4 \* T' k; B
Q: 上传模板后 DIY 模块消失
1 I' e& L+ k, NA: 到 data/diy/template/模板名 下面寻找 .bak 文件,重新 diy,选择恢复这个文件即可。
+ C2 ^% C" m) u  C; T+ d3 _2 k/ N& l1 \: q" Q6 D" b3 ]
Q: 部分论坛设置、插件设置行为诡异或设置丢失% ]' X; E0 V0 o( o
A: 很大可能是第 4 步修复数据库时,migrate_db.php 没有处理到相关数据表的字段。请仔细检查有无漏掉的数据表字段。
* e1 N* f; _! e  @
6 Z2 |# r0 b' c0 J1 m8 HQ: 如何方便地批量转换编码?" B( q$ f# a1 Q$ B  A  A" O
A: 在 Linux 环境可以使用 iconv 命令(请稍微学习一下这条命令,使用很方便)。在 Windows 下可以使用 Codepage Converter 这个工具(已在附件提供)。1 Y* t3 c# P: m' t) S$ u3 o3 Q

快速回帖 使用高级回帖 (可批量传图、还有插入视频等功能哦!)

您需要登录后才可以回帖 登录 | 注册

  • 发布信息免费
  • 发贴彩色标题
  • 签到额外经验值

如何快速提升等级,查看[积分规则]

活动中心

查看更多>>
最新热版
会员排行
©2009-2016 西班牙华人网 http://www.laicw.eu西班牙文化部注册管理西中文化传媒促进会主办Powered byDiscuz!X3"世界华文媒体合作联盟"成员 || | 联系站长
发帖 客服 微信 手机版 举报