2011年3月24日 星期四

【保証成功】的 mysql 中文亂碼解決方案

http://ria.richtechmedia.com/category/phpmysql/

自從寫完下面兩篇文章:

wordpress 1.5升級注意事項 - 中文亂碼篇

mysql 4.1中文亂碼第二擊

過去幾個月就不斷有來信詢問各種 mysql 中文相容的問題,所以有機會看到許多玩家們用的各式連接法與程式,實在太開眼界。

最近因為轉換到 flex 2做為開發平台並重寫一些產品,許多去年寫的 framework 就無法使用,而其中有部份專門處理多國語系的library也隨之失效,導致我得重新面對這個問題,所以正好籍此機會將一些新心得整理出來。

*mysql中文亂碼的原因

mysql 會出現中文亂碼的原因不外乎下列幾點:

-mysql server本身設定問題,例如還停留在 latin1

-mysql table 的語系設定問題(包含 character 與 collation)

-客戶端程式(例如 php) 的連線語系設定問題

在之前的兩篇文章中已介紹過如何設定 mysql server/table 的 character/collation。

接下來只需要補充幾點注意事:

*mysql中文亂碼必勝解決法

1、mysql 啟動時會讀取一個預設的 config 檔,一般名稱為 my.ini,而它會到下列兩位置去尋找這個檔案:

C:\windows\my.ini 也就是作業系統的安裝目錄,也有可能是 C:\winnt\my.ini
C:\:my.cnf 也就是 C disk 的根目錄

注意不同位置裏的檔案suffix不一樣,這點在之前的文章中沒有特別強調,因此那時我是用更複雜的方法直接重新將mysql 註冊到 service裏面,並在那裏指定 my.ini的位置。

2、my.ini 裏的內容為:

[mysqld]
default-character-set=utf8

[client]
default-character-set=utf8
init_connect='SET NAMES utf8'

其中 mysqld 是指定 server啟動時要用的語系,但如果這裏設定為 utf8可能會讓許多英文軟體不開心,例如 osCommerce/mediaWiki,所以這裏建議設成 latin1。

下面的 client 則是設定當 client 連線時要使用什麼語系,但可惜的是這個設定不是每個client都會鳥它,基本上只有 mysql 自已家的程式,例如 mysql.exe, mysqld.exe, mysqladmin.exe 或是 MySQL Control Center這種程式會去讀取這個設定檔然後改用 utf8 連線。

note: 感謝 b6s 桑熱情相助提供第二行指令,據說比一支支php程式去設定connection setting更快,這樣應該也可以順便解決phpmyadmin無法正確顯示 unicode 中文的問題(不過 amfphp 到是不吃這套,一定要乖乖的自已設定語系才行)

但大部份工程師應該都是自已寫 php/jsp 程式去連線,此時自然不會讀取這個設定而繼續使用預設的語系 - latin1。

這也正是八成來信朋友陣亡的地方。

通常我會用一個獨立的檔案來處理 mysql connection的設定,例如:

PLAIN TEXT

PHP:

  1. <?

  2. //database connection details.

  3. $host = "localhost";

  4. $link = mysql_connect($host, "xxx", "xxx");

  5. mysql_query("SET NAMES 'utf8'");

  6. mysql_select_db("your_table_name_here", $link);

  7. ?>

請注意在 mysql_connect後第五行的地方有加上一個 "set names 'utf8' "的指令,告訴mysql 這個 connection 之後的連線內容都要使用utf8,經過這樣設定後,通常就可以解決大部份問題。

從這裏也可以推想得知,如果你有用某種custom connection pooling機制,就要記得在每次建立新的connection後立即設定為 utf8。

這組設定經過幾天的反覆測試(使用中文繁、簡、日文、韓文)後已經証實完全不會有亂碼或是某些字變成 "口"。

例子:試者輸入這幾個字「不道可否囉」如果它們能正確進入mysql再被讀出來,那就是中文沒問題了,如果讀出來後變成『口』字那就是革命還未成功同志仍需努力...orz

當然我也順便驗証了 flex2 - amfphp - php - mysql 來回傳resultset 也不再會有中文亂碼問題,可以安心使用囉。

comments(23) | by jeremy

mysql 4.1中文亂碼第二擊

In php/mysql   August 14, 2005 - 11:34 am

自從貼了wordpress 升級與mysql中文亂碼這篇後,大概每天都有有幾十個依此關鍵字而來的網友,同時也接到一些email詢問大同小異的亂碼問題,仔細想想後覺得還是把這個問題再解釋清楚一點。

首先,要讓mysql 4.1正確顯示中文最簡單的方法就是全程使用 utf8,從網頁到連線到資料庫等,而my.ini的設定如下:

[mysqld]
default-character-set=utf8

#settings for clients (connection, results, clients)
[mysql]
default-character-set=utf8

其中 [mysqld] 是設定 mysql啟動時要採用的語系,而[mysql]則是通知外來的連線client(例如php頁面或 flash 程式)要使用何種語系設定。

這個設定方法對一般的開發工作非常適用,但有個小缺點,就是當使用一些open source php程式時(尤其是英文寫的程式),如果這些程式語法還停留在mysql 4.0時代,那上面的設定就會導致中文顯示變的怪怪的,最明顯的情況就是大部份中文都顯示的出來,但少部份會變成 方塊型+問號 的亂碼,例如「裏」這個字幾乎是穩死。

這種情況我個人在 drupal 與 gregarius(一個php rss reader) 上見過,經過一番debug才發現了上述原因,後來終於找到解決方法。

最簡單的方式就是不要下面這段:

[mysqld]
default-character-set=utf8

拿掉這段後會讓mysql 啟動時停留在預設的latin-1語系,這樣會讓大部份英文程式都很快樂,而要使用utf8中文的人,只要記得建資料庫時將它設成utf8,然後保留 [mysql] 這段設定,讓中文程式正確的使用utf8與它溝通即可。

經過測試,這樣改良後的設定,使用常見的英文php軟體(如wordpress, drupal, OSCommerce, gregarius)都沒問題,而我每天開發要用的 flash - amfphp - php - mysql 黃金組合也同樣ok。

发表于: 2007-04-06,修改于: 2007-04-06 16:08 已浏览2520次,有评论0条 推荐 投诉

沒有留言: