本帖最后由 kelvinhan 于 2008-10-25 12:45 编辑
近日遇到一个项目,需要把dvbbs7.1 转换到 discuz6.1, 论坛版本及系统环境如下:
源论坛:DVBBS7.1 SQL SP1 Business(GBK编码,数据文件大约13G) 系统环境:Winows2003 + Mssql2005
目标论坛:DISCUZ6.1+UCenter(UTF8编码),系统环境: Redhat rh4 + Mysql + PHP + APACHE
两台服务器都有独立的广域网地址。另外,两台服务器还通过另外的网卡(1G速率)直连。
查阅了一下DISCUZ论坛,发现关于这两种论坛转换的文章有很多,而且又有DISCUZ官方出的 xconvert(1.3)工具,加之本人早有这方面的转换经验(https://discuz.dismall.com/viewthread.php?tid=484197,6.0SQL to DZ5.0,06年12月份),当初想象转换应该很容易。
先总结一下网上的转法:
1、安装 discuz6.1+ucenter GBK版
2、利用 xconverter1.3 转换
3、安装 discuz6.1+ucenter utf8版
4、利用mysql工具(mysqldump)导出数据库成SQL文件,再转码成utf8,再将里面恢复数据语句中关于编码的GBK改成utf8,然后导入
或者利用 DZ后台的备份工具保存成 utf8, 然后导入
最初,也按照上面的转法实践过(在WINDOWS2003服务器上配置PHP/MYSQL环境,在相同的机器上转换),但是转换速度很不理想,而且 Windows 2003 的远程 rdp 操作非常慢(带宽一共20兆,加之论坛在线人数非常多,转换程序运行时,时常会出现网页无法打开的情况,导致自动转换中途中止)。
在经历几次失败后,最终,经过研究,发现了如下最为理想的直转方案,现将转换过程及经验分享如下:
一、转换服务器配置(运行 xconvert 1.3 的 Redhat服务器)
因为在LINUX下的PHP默认是不支持连接 Mssql 数据库的(只有windows版本的 php_mssql 模块),所以我们需要通过手工编译 FreeTdS 及 PHP来实现
之所以能够从 Dvbbs GBK 直接转换升级到 Discuz6.1 UTF8,也是利用了 FreeTDS的一些内置特性。
另外,使用 FreeTDS, 不用修改MsSQL数据库结构(此特性未经确认是否因为FreeTDS。不过,确实确实无须把nText 修改成 Text)
1、编译FreeTDS的大致过程:
wget ftp://ftp.ibiblio.org/pub/Linux/ ... /freetds-stable.tgz
tar xzf freetds-stable.tgz
./configure --prefix=/usr/local/freetds
make
make install
2、编译PHP的大致过程:
wget http://cn.php.net/get/php-5.2.6.tar.gz/from/cn2.php.net/mirror
tar xzf php-5.2.6.tar.gz
./configure --prefix=/usr/local/php --with-apxs2=/usr/local/apache2/bin/apxs --with-mssql=/usr/local/freetds +其它的参数
make
make install
技巧:
为了使编译出来的PHP最大程序和以前版本的 PHP 兼容,configure 的其它参数,请保持和以前版本的一致。编译参数很长,可以通过 phpinfo()函数得到,然后粘贴到命令行即可。
3、配置FreeTDS:
修改 /usr/local/freetds/etc/freetds.conf
[global]
client charset = utf8 #关键步骤,使您直接转换到UTF8
[MsServer70] #该段为MsSql的配置,可以在 linux的php中用 $link = mssql_connect( "MsServer70", '用户名', '密码'); 来连接了
host = 192.168.1.1 #mssql 局域网地址
port = 1433
tds version = 7.0
二、技巧分享:
1、为了使xconvert 的转换日志正确的存入 xreporter数据表,您可以把 xconvert 中的php 文件转换成 utf8 格式。
在 linux 下,可以使用如下命令:iconv -f gbk -t utf8 step_x.php
示例:
mv step_1.php step_1.php.bak
iconv -f gbk -t utf8 step_1.php.bak > step_1.php
2.、手工修改 官方DZ及UCenter用户名长度
因为 dvbbs 中 用户名长度为 nvarchar(50),而 dz 中,无论是GBK还是U8版本,其用户长度只有 char(15),这样会造成大量的用户转换丢失。我们只能手工修改官方的数据库长度以适应,并且修改 step_1.php中的相应判断代码。
3. 官方的转换代码中发现的BUG
在转换过程中发现了一些官方代码中的BUG:
A:如果内容中有特殊字符,在极特殊的情况下,构造出的sql语句会是非法sql语句,这样会导致转换出错。
这个问题是如下过程造成:
官方的转换过程(原理):
$len = 50;
$str = addslash($str);
$str = cutstr(htmlspecialchars( $str, $len)
例如在cutstr 之前的字符串是 '我说\"abcdef\"'
如果恰巧cutstr,把字符串结尾的 " cut 掉
那么 插入的字符串就变成了 '我说\"abcdef\', 这个语句在 mysql 中是错误的.
这个错误,在DZ论坛中的解决方案是,手动编辑 sqlserver 数据库中导致错误的内容。
如果贴子量大,这种方法会死的 :)
B:转换论坛版区的算法可能存在问题
官方的转换过程:
从 dvbbs.board 表中读出所有记录,并且循环处理
从 board['settings']取出 专题数据
$settings = explode(',', $forum['board_setting']);
threadtypes_arr = explode('$$', $settings[48]);
unset($threadtypes_arr[$st_sum-1]);
然后循环 $threadtypes_arr, 插入到 cdb_threadtypes 中
foreach ($threadtypes_arr as $key => $value) {
$typeid = $key+1;
}
如果多个版块存在着专题定义,那么,生成的 typeid 会重复,在插入到数据库时,因 typeid 是主键,故会导致错误。 |