WZ111
论坛总版主
论坛总版主
  • UID3
  • 粉丝1
  • 关注0
  • 发帖数102
  • 社区居民
阅读:3954回复:0

[MySQL]安全快速的数据库编码转换php脚本

楼主#
更多 发表于 2014-04-30 15:36
今天碰到了数据库编码的问题,因为数据库整合的原因,发现以前的DEDECMS数据库编码为latin1,而论坛数据库编码为utf8,这样的话DEDECMS调用论坛数据就会出现“????”的乱码,怎么解决呢,只好把DEDECMS的数据库编码转换为utf8了,网上搜不出来简单方法,只能使用PHP脚本执行,使用前先备份好数据库,然后在网站目录下新建一个php文件:
<?php
 
/*$mysql_host       = 'localhost';          //MySQL主机
$mysql_user     = 'root';               //MySQL用户名
$mysql_psword   = '';       //MySQL密码
$fromdb         = '';           //原本数据库
$intodb         = '';           //新的空数据库
$per            = 20;               //每次跳转处理的数据库条数
$intodbcharset  = 'utf8';            //设置的编码
*/
/*
本程序可以实现latin1<->utf8,utf8<->utf8,utf8<->big5,的编码的相互转换,程序可以进行多次转换即可以实现latin->utf8->utf8等的转换
*/
$phpselfname=$_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
@set_time_limit(0);
error_reporting(7);
define('D_P',__FILE__ ? dirname(__FILE__).'/' : './');
foreach($_POST as $_key=>$_value){
    !ereg("^\_",$_key) && $$_key=$_POST[$_key];
}
foreach($_GET as $_key=>$_value){
    !ereg("^\_",$_key) && $$_key=$_GET[$_key];
}
$charsetdb=array('latin1'=>'utf8','utf8'=>'utf8','utf8'=>'big5');
if(!$action){
    echo "<table align=center><tr><td>本程序的作用:转换数据库编码。</td></tr><tr><td><font color=\"#FF0000\">警告:如果您填写的目的数据库已经存在,原来的数据将被删除并重建空的新数据库使用前务必备份数据库,否则操作出错后后果严重!电脑技术网 www.it892.com</font></td></tr></table>";
    $charsets=array('big5','utf8','latin1','utf8');
    $options="<option value=\"\">";
    foreach($charsets as $value){
        $options.="<option value=\"$value\">$value";
    }
    echo "<form method=post action=\"$phpselfname\">
    <input type=\"hidden\" name=\"action\" value=\"creattable\">
    <table align=center>
    <tr>
        <td colspan=2>请先设置以下参数:</td>
    </tr>
    <tr>
        <td>数据库主机:</td>
        <td><input type=\"text\" name=\"mysql_host\" value=\"localhost\"></td>
    </tr>
    <tr>
        <td>数据库用户名:</td>
        <td><input type=\"text\" name=\"mysql_user\"></td>
    </tr>
    <tr>
        <td>数据库密码:</td>
        <td><input type=\"text\" name=\"mysql_psword\"></td>
    </tr>
    <tr>
        <td>源数据库名:</td>
        <td><input type=\"text\" name=\"fromdb\"></td>
    </tr>
    <tr>
        <td>目的数据库名:</td>
        <td><input type=\"text\" name=\"intodb\"></td>
    </tr>
    <tr>
        <td colspan=2><font size=\"1\" color=\"#3300FF\">创建一个新的空数据库,建议不要填写以有的数据库名</font></td>
    </tr>
    <tr>
        <td>目的数据库编码设置:</td>
        <td><select name=\"intodbcharset\">$options</select></td>
    </tr>
    <tr>
        <td colspan=2><font size=\"1\" color=\"#3300FF\">编码转换限制说明:latin1<->utf8,utf8<->utf8,utf8<->big5</font></td>
    </tr>
    <tr>
        <td>每次跳转处理数据条数:</td>
        <td><input type=\"text\" name=\"per\" value=2000></td>
    </tr>
    <tr>
        <td colspan=2><font size=\"1\" color=\"#3300FF\">如果涉及big5的转换,请设置的尽量小点本人在本地机子上测试只能一次转换五六十个</font></td>
    </tr>
    <tr>
        <td colspan=2 align=center><input type=\"submit\" value=\"开始运行\"></td>
    </tr>
    </table></form>";
    exit;
}
!$mysql_host && Showmsg("请填写数据库主机!",$phpselfname);
!$mysql_user && Showmsg("请填写数据库用户名!",$phpselfname);
!$fromdb && Showmsg("请填写要处理的源数据库",$phpselfname);
!$intodb && Showmsg("请填写要保存的新的数据库名(将被创建,如果已经存在将被删除重新创建)",$phpselfname);
!$per && Showmsg("请填写每次跳转处理的数据库条数,必须为整数!",$phpselfname);
!$intodbcharset && Showmsg("请选择新数据的编码!",$phpselfname);
$andurl="mysql_host=$mysql_host&mysql_user=$mysql_user&mysql_psword=$mysql_psword&fromdb=$fromdb&intodb=$intodb&per=$per&intodbcharset=$intodbcharset";
!$start && $start=0;
!$part && $part=0;
$mysql = mysql_connect($mysql_host,$mysql_user,$mysql_psword) or die("Could not connect : " . mysql_error()); 
//mysql_query("SET NAMES '$fromdbcharset'");
mysql_query("SET sql_mode=''");
@mysql_select_db($fromdb) or die("源数据库 $fromdb 不存在!");
$tablesdb=array();
$Tables_in='Tables_in_'.$fromdb;
$query=mysql_query("SHOW TABLES");
while($rt=mysql_fetch_array($query,MYSQL_ASSOC)){
    $tablesdb[]=$rt;
}
$table=$tablesdb[$part][$Tables_in];
$tableinfo=array();
$query=mysql_query("SHOW TABLE STATUS LIKE '$table'");
while($rt=mysql_fetch_array($query,MYSQL_ASSOC)){
    $charsetpos=strpos($rt['Collation'],'_')===false ? -1 : strpos($rt['Collation'],'_');
    $rt['Collation']=substr($rt['Collation'],0,$charsetpos);
    $tableinfo=$rt;
}
if($charsetdb[$tableinfo['Collation']]!=$intodbcharset && $charsetdb[$intodbcharset]!=$tableinfo['Collation'] ){
    Showmsg("编码设置错误!".$tableinfo['Collation']." 编码不能转换为 $intodbcharset 编码",$phpselfname);
}
unset($charsetdb);
mysql_query("SET NAMES '$tableinfo[Collation]'");
if($action=='creattable'){
    $tablecreat=array();
    foreach ($tablesdb as $key => $value){
        $query=mysql_query("SHOW CREATE TABLE $value[$Tables_in]");
        while($rt=mysql_fetch_array($query,MYSQL_ASSOC)){
            echo $rt['Create Table'];
            $rt['Create Table']=str_replace("$tableinfo[Collation]","$intodbcharset",$rt['Create Table']);
            $tablecreat[]=$rt;
        }
    }
    mysql_close($mysql);
    $mysql = mysql_connect($mysql_host,$mysql_user,$mysql_psword) or die("Could not connect : " . mysql_error());
    mysql_query("DROP DATABASE IF EXISTS `$intodb`") or die("DROP DATABASE failed : " . mysql_error());
    if(mysql_get_server_info() > '4.1'){
        mysql_query("CREATE DATABASE `$intodb` DEFAULT CHARACTER SET $intodbcharset") or die("Query failed : " . mysql_error()); 
    }else{
        mysql_query("CREATE DATABASE `$intodb`") or die("Query failed : " . mysql_error()); 
    }
    echo "$intodb 数据库创建成功!";
    mysql_query("SET NAMES '$intodbcharset'");
    if(mysql_get_server_info() > '5.0'){
        mysql_query("SET sql_mode=''");
    }
    @mysql_select_db($intodb) or die("目的数据库 $intodb 不存在!");
    foreach ($tablecreat as $key => $value){
        mysql_query("DROP TABLE IF EXISTS `$value[Table]`");
        mysql_query($value['Create Table']);
        echo "$value[Table] 表创建完成";
        $conut++;
    }
    mysql_close($mysql);
    echo "所有的表创建完成,数据库共有 $conut 个表!";
    redirect("$phpselfname?action=data&$andurl");
}elseif($action=='data'){
    $conut=0;
    $data=array();
    if($table){
        echo "正在转移 $table 表的从 $start 条记录开始的后 $per 条记录";
        $query=mysql_query("SELECT * FROM $table LIMIT $start,$per");
        while($rt=mysql_fetch_array($query,MYSQL_ASSOC)){
            $data[]=$rt;
        }
        mysql_close($mysql);
        unset($rt);
        $mysql = mysql_connect($mysql_host,$mysql_user,$mysql_psword) or die("MySQL链接错误!");
        if($tableinfo['Collation']=='utf8' || $intodbcharset=='utf8'){
            $intodbcharset=$tableinfo['Collation'];
        }
        mysql_query("SET NAMES '$intodbcharset'");
        if(mysql_get_server_info() > '5.0'){
            mysql_query("SET sql_mode=''");
        }
        @mysql_select_db($intodb) or die("phpwind数据库不存在!");
        if($start==0){
            mysql_query("DELETE FROM $table");
        }
        if($tableinfo['Collation']=='big5' || $intodbcharset=='big5'){
            require_once('chinese/chinese.php');
            $chs = new Chinese($tableinfo['Collation'],$intodbcharset);
        }
        foreach($data as $key =>$value){
            $sql='';
            foreach($value as $key1 => $value1){
                if($tableinfo['Collation']=='big5' || $intodbcharset=='big5'){
                    $value1=$chs->Convert($value1);
                }
                $value1=addslashes($value1);
                $sql=$sql ? $sql.",'".$value1."'" : "'".$value1."'";
            }
            mysql_query("INSERT INTO $table VALUES($sql)") or mysql_errno();
            $conut++;
        }
        mysql_close($mysql);
        if($conut==$per){
            $start+=$per;
            redirect("$phpselfname?action=data&part=$part&start=$start&$andurl");
        }else{
            $part++;
            redirect("$phpselfname?action=data&part=$part&$andurl");
        }
    }else{
        echo "数据库$fromdb 编码 $tableinfo[Collation] 转移到数据库 $intodb 编码 $intodbcharset 完成!";exit;
    }
}
 
function redirect($url) {
    echo"<script>";
    echo"function redirect() {window.location.replace('$url');}\n";
    echo"setTimeout('redirect();', 2000);\n";
    echo"</script>";
    echo"<a href=\"$url\">如果您的浏览器没有自动跳转,请点击这里</a>";
    exit;
}
function Showmsg($message,$url) {
    echo $message,"<a href=\"$url\">点这里返回</a>";exit;
}
?>
本脚本的界面如下:

描述:数据库编码转换

图片:QQ截图20140430153040.jpg

数据库编码转换


点击开始运行后,会将现在的数据库编码转换为预定的编码,也就解决了数据库编码难转换的问题!
将帖子分享到:
喜欢0 评分0

返回顶部