MySQL和phpMyAdmin工具與UTF8中文亂碼的終極研究

原贴:http://www.adsenseor.com/mysql/256.html

MySQL和phpMyAdmin工具與UTF8中文亂碼的終極研究

這篇不是探討SEO, 出現在AdSenseor或許有些奇怪,不過因為最近筆者勤於備份資料,而且試著把建立在MySQL資料庫中的資料在各種平台轉來轉去,發現了許多的問 題,而這些問題在網路上有許多網友問過,但看到很多人找不出答案,因而放棄重裝系統或者放棄掉寶貴的舊有資料,那麼我相信筆者這一篇文章可能會讓您放棄掉 堅持在所謂的”UTF-8中文亂碼”的迷思。

為什麼筆者稱之為”迷思”,許多使用PHP程式語言搭配MySQL資料庫的朋友百分之一百零一會使用phpMyAdmin,但隨著MySQL資料庫 版本的升級,phpMyAdmin資料庫管理工具也跟著改版,曾幾何時您會發現,原本使用phpMyAdmin工具可以在資料表中看到的中文,變成了亂 碼。

狀況(1) phpMyAdmin未升級前正常,升級後中文變亂碼

測試環境 

phpMyAdmin版本:2.5.6
MySQL版本:4.1.8-nt
架站環境:Appserv - Win32
網站的預設編碼:big5
儲存於MySQL的編碼:latin1

mysql2.gif

phpMyAdmin版本:2.6.1 rc-1
MySQL版本:4.1.8-nt
架站環境:Appserv - Win32
網站的預設編碼:big5
儲存於MySQL的編碼:latin1

mysql1.gif

phpMyAdmin工具版本升級後,結果中文變成亂碼。

這種情況並不會影響前台輸出中文,所以訪客瀏覽網頁時一樣正常,差別在於自己在phpMyAdmin時工作並不方便,中文都變成了亂碼的原因在於瀏 覽器預設的檢視編碼不同,原本舊版的2.5.6版以預射big5繁體中文去檢視網頁,而這個版本以後的新版phpMyAdmin一律都以UTF-8檢視, 因此才會變成亂碼。

mysql3.gif

這並不會影響到原本儲存於資料庫中的資料,所以大可不用擔心,解決的方法就是使用舊版的phpMyAdmin或者自己寫一套資料庫管理工具、另外找尋非UTF-8檢視的資料庫管理軟體。

狀況(2) 中文UTF-8編碼網站,前台瀏覽正常,phpMyAdmin檢視中文變成亂碼

測試環境 

phpMyAdmin版本:2.6.1 rc-1
MySQL版本:4.1.8-nt
架站環境:Appserv - Win32
網站的預設編碼:UTF-8
儲存於MySQL的編碼:UTF-8

也許很多朋友和筆者和MySQL中文亂碼奮戰的時候,會看過很多”品種”的中文亂碼,為什麼phpMyAdmin已經是用UTF-8檢視網頁了,看到的結果仍舊是火星文,後來經過反覆的測試,筆者先規納出以下的圖表作說明: 

mysql4.gif

一般而言,初次安裝Appserv架站軟體或者在Linux系統中建立MySQL資料庫,預設的資料庫編碼及資料傳送方式都會是latin1,從一 個不是UTF-8的網頁表單中鍵入資料,送出到處理的php程式,它取得的字串就不會是UTF-8編碼,而以latin1的編碼儲存到資料表欄位中,最終 的編碼也是latin1。所以只要用舊版的phpMyAdmin去瀏覽,看到的一樣會是正常的中文字。

而UTF-8網站的處理過程如下圖:

mysql5.gif

在UTF-8網頁中的表單輸入資料,其資料在UTF-8網頁中可以檢視,因為當輸入的時候該資料本身就是UTF-8編碼的資料,當送出表單時,這些 UTF-8的資料會經過資料庫的處理存入欄位中,因為MySQL資料庫預設傳送的編碼是latin1,所以它把UTF-8編碼資料以latin1編碼存入 資料表的欄位中,而變成亂碼。但這個亂碼仍然是UTF-8編碼的,只是因為被latin1給弄亂了,所以不管是用什麼樣的編碼語系去讀取這些字串,看到的 只是亂碼,不可能讀的出正常的中文字串。

當前台的程式呼叫時(例如phpbb論壇),MySQL資料庫會以latin1將這些亂碼”還原”成”正常”的UTF-8中文字。

在latin1的預設編碼下,不管怎麼在phpMyAdmin更改資料庫、資料表、資料表欄位的連線校對為utf8_general_ci、utf8_unicode_ci或latin1_swedish_ci等編碼,都會是一樣的結果,看到的都會是同一款品種的火星文。

如果您想要在phpMyAdmin中看到UTF-8顯示正常的中文字,以下有兩種解決方案:

更改MySQL預設的連線編碼設定
Linux或Unix-like環境

找出 /etc/my.cnf 檔案,這個檔案是MySQL資料庫的設定檔,詳細的說明請參閱vbird的WWW伺服器#MySQL效能調校,內文有更詳細的參數說明,但在此很簡單地只要改兩個地方就可以讓MySQL預設的latin1編碼連線方式改成UTF-8。

mysql6.gif

Win32 - Appserv架站軟體

在Windows環境下,則MySQL設定檔為my.ini,一般而言存放在c:/window 這個目錄底下,同樣地找尋上述兩個地方將其從latin1改成utf8。

程式語法限定MySQL傳送的編碼

在此以phpBB2論壇為例,在db.php中第60行以後加入以下指令,告知MySQL都以UTF-8的方式傳送資料:

mysql71.gif

筆者將一個UTF-8網站,但MySQL是預設latin1連線的網站,在讀取資料庫的程式碼中,加入如上圖示第62行的程式碼之後,網頁上只要是從資料庫讀出來的中文字都變成了亂碼,但試著新增一筆資料,結果如下:

mysql8.gif

宣告以UTF-8編碼連線後,原本好好的UTF-8中文都變成亂碼了,因為那些資料原本都是以latin1重編過的UTF8資料要以latin1編碼呼叫才能夠還原出原本的UTF-8中文字,但現在強制以UTF-8編碼連線,就無法還原了,因此,讀者們看到的火星文和資料庫中的一模一樣地出現在網頁上。

mysql9.gif

宣告以UTF-8編碼連線後,所輸入的中文字,終於可以在phpMyAdmin中看到,這可是確確實實的UTF-8中文,而不是被latin1編碼 搞亂的中文字。但是看看上圖藍色框框的部份,不同品種的火星文出現了!但是那些中文字都變成了一堆??????????????問號,這是為什麼呢?看看 下圖,筆者相信讀者們的觀念就釐清了。

mysql10.gif

因為在筆者的測試中,只有把第二個欄位的連線效對改成UTF-8,其它都一樣還是維持latin1的連線效對,也就是說,如果全部以UTF-8編碼的方式,確實地在phpMyAdmin等以UTF-8檢視的資料庫管理軟體中看到非亂碼的中文字,不但MySQL的連線部份要UTF-8編碼,資料表的欄位也必須用UTF-8的連線較對,否則會失敗。

mysql11.gif

上圖為在MySQL中存入正確的UTF-8中文字的流程,作為本例的一個結束。

狀況(3) 中文UTF-8編碼網站,在其它Hosting使用mysqldump指令備份,mysql指令匯入正常,但在MySQL 4.x部份中文錯亂或匯入失敗

相信一定會有讀者遇到這種情況,由其是在外國租用Hosting空間或VPS的讀者,因為外租的主機是不可能為單一個戶去改變系統的預設值的,尤其 在英語系國家,存在任何字碼,英文字還是英文字,並不會因為說存在不同的編碼就變成亂碼,所以一律都是預設的。因此,在沒辦法去要求主機商將MySQL的 連線編碼改成big5或UTF-8的情況下,一切都只能靠自己解決了。

用mysqldump指令備份資料庫是最完整的方法,而且不需要將主機服務停止就可以隨時備份,但注意,如果您是採取完美顯示UTF-8中文字的解決方案在沒辦法使用UTF-8編碼連線的狀況下,在國外預設為latin1的主機下使用mysql指令匯入資料庫會失敗!

即使自己的主機預設是latin1,國外的主機預設也是latin1,照理說用mysqldump指令備份,mysql指令還原,會非常順利,但筆 者在測試的過程中發現,某些情況下,部份UTF-8中文字正常,但部份中文字會跳字(變成其它字)和變成亂碼,後來筆者發現,這是因為Mysql資料庫版 本不同而發生的,當筆者在MySQL版本4.1.8(預設連線編碼latin1)的情況下使用mysqldump備份,傳到國外主機,MySQL版本為5 (預設連線編碼latin1),用mysql指令匯入,非常地順利,一下子網站就可以正常運行了,中文字也正常地顯示在網頁上。

但當筆者要備份國外主機的資料庫回自己的主機時,卻發現匯入時指令中斷,打開備份檔將有問題的SQL字句都刪除後,再匯入,雖然順利匯入到資料庫中 了,但中文字卻出現跳字和部份亂碼的情況,筆者研判是,版本相容性的問題,舊版本的備份檔可以匯進新版本的MySQL資料庫,但從最新版本的資料庫備份出 的檔案要匯進舊版本可能就會發生問題了。

最後筆者將自己測試用的主機MySQL的版本也從4.1.8升級到5系列版本,在國外主機備份的檔案,一下子就順利匯入了,也不再有中文字跳字及部份亂碼的情況發生。

附錄

MySQL資料庫備份語法

如果您是使用Appserv架站軟體,那麼先從開始列 - 執行 - 輸入: cmd

mysql12.gif

接下來會出現以下視窗,對於不熟DOS介面的讀者跟著輸入指令就可以了。

mysql13.gif 

指令是:

mysqldump - -opt database > backup-file.sql

其中- -opt (這是兩個-連在一起,因為本網站程式會將連在一起的減號取代字串) 是快速完整備份的指令,紅色字的database是您要備份的資料庫名稱,綠色字的 backup-file.sql是匯出而產生的備份檔,可自由命名。在Linux也是用這個語法。

MySQL資料庫匯入備份檔語法

指令是:

mysql database < backup-file.sql

  
後記

希望這篇教學文章可以省掉讀者們不少時間,筆者花了許多時間在和這些中文亂碼搏鬥,只求一個安心的備份方式,後來有些心得,仍覺得在網路上還沒有一 篇文章比較詳細具體的說明相關的狀況,所以筆者花了約6個小時準備這篇文章,如果可以省下一位讀者10個小時的摸索和試誤,1000個讀者就為這個地球省 下10000個小時的時間了, 而筆者需要的是您花30秒迴響給我的鼓勵與支持,謝謝,希望對您有幫助。

轉貼請註明出處
專題作者:林新邦 / 資深網頁設計工作者
AdSenseor網路觀察家 :: AdSense & SEO 專題研究
網址:http://www.adsenseor.com

加入書籤:  把這個遊戲加入黑米書籤 把這個遊戲加入MyShare書籤 把這個遊戲加入furl書籤

4 Responses to “MySQL和phpMyAdmin工具與UTF8中文亂碼的終極研究”

  1. dasu88 提到:

    謝謝您這一篇文章,釐清了我不少的疑惑。
    謝謝!

  2. thanks 提到:

    大感謝! 你幫我省下不只10小時

  3. littleshell 提到:

    可是某些時候在phpmyadmin工作是不方便
    但在ms-dos中又不能把字碼頁轉成utf8
    我又該如何呢

  4. admin 提到:

    littleshell 您的問題是.. ?

    如果是狀況1, 下載舊版的 phpmyadmin 就解決了.

留下一個迴響

您必須登入才能發表迴響。

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值