WordPress 與 MySQL 的 Encoding 大混戰…

週五晚上終於順利解決這個煩人的 encoding 問題

週五(Mar. 7, 2008)的時候原本是打算幫自己的blog換一個新的theme,找了一陣子覺得green love這個看起來不錯。反正黑色底色拿來擺照片會有集中視覺注意力的效果,而黑底白字看起來也蠻舒服的。

下載之後卻發現換不上去,求教布丁大大之後,猜測是green love這個theme有用到新的東西,所以我應該要先升級才是(from 2.0.7 to 2.3.x)。好吧,那就開始來備份資料庫。

沒想到備份完之後赫然發現,怎麼mysqldump出來的東西中文字全部都變成亂碼了!!再次向布丁大大求救,才發現原來是wp-db.php裡頭根本沒指定query的encoding為utf8,即使mysql裡頭用utf8儲存了,但是還是會有這個鬼問題發生。

好,所以應該要把資料做encoding transformation,對這方面實在不熟,後來找到可以用iconv來完成,布丁建議可以用piconv。可是轉了幾次都還是不行,甚至一度開始想要自己寫程式把整個blog的文章一篇一篇透過http全部掃回來的方法。

到了半夜布丁也宣告放棄。正當準備開始想著手寫程式的時候突然想到,ㄟ,如果是因為wp-db.php沒有指定encoding,那這樣等於是所有的query都是用latin1的方式跟mysql做溝通。等於是在編寫blog資料的時候是用utf8編碼,但是在wordpress與mysql中間傳資料的過程這些utf8編碼的資料是被當成latin1編碼,mysql存取的時候又把這些latin1編碼的資料變成utf8編碼來處理。

那,如果在mysqldump的時後用latin1的方式dump出來,那這樣應該會是正常utf8的中文字(但是顯示文字的時候會是以latin1編碼,所以看起來會是亂碼)。如果這個猜測是對的,那應該可以把它轉成big5?

所以我下了這樣的command

mysqldump -u user -p --default-character-set=latin1 database > mysqldump_db_latin1.sql

piconv -f utf8 -t big5 < mysqldump_db_latin1.sql > mysqldump_db_big5.sql

開啟mysqldump_db_big5.sql之後可以看到正常的中文字!喔耶!果然被我猜對了!(開始跳起藍藍路?!)

那接下來再把它轉回去utf8...

piconv -f big5 -t utf8 < mysqldump_db_big5.sql > mysqldump_db_final_utf8.sql

喔耶!還是正常的中文字,連日文字也統統都看得到了 😀

最後再把mysqldump_db_final_utf8.sql開頭的

/*!40101 SET NAMES latin1 */;

換成

/*!40101 SET NAMES utf8 */;

然後把原本資料庫的table內容清一清,再把資料restore回去。然後在wp-db.php裡面找到

$wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);

再後面加上一行

$wpdb->query("SET NAMES 'utf8'");

一切就大功告成!

 

整個過程真的感謝布丁大大的支援。另外,不曉得這一篇對科科DK大大很久之前的問題有沒有幫助?

註:原來類似的問題也有人用同樣的方法解過,MySQL 編碼老問題解決過程記錄