標籤

4GL (1) 人才發展 (10) 人物 (3) 太陽能 (4) 心理 (3) 心靈 (10) 文學 (31) 生活常識 (14) 光學 (1) 名句 (10) 即時通訊軟體 (2) 奇狐 (2) 音樂 (2) 產業 (5) 郭語錄 (3) 無聊 (3) 統計 (4) 新聞 (1) 經濟學 (1) 經營管理 (42) 解析度 (1) 遊戲 (5) 電學 (1) 網管 (10) 廣告 (1) 數學 (1) 機率 (1) 雜趣 (1) 證券 (4) 證券期貨 (1) ABAP (15) AD (1) agentflow (4) AJAX (1) Android (1) AnyChart (1) Apache (14) BASIS (4) BDL (1) C# (1) Church (1) CIE (1) CO (38) Converter (1) cron (1) CSS (23) DMS (1) DVD (1) Eclipse (1) English (1) excel (5) Exchange (4) Failover (1) FI (57) File Transfer (1) Firefox (2) FM (2) fourjs (1) gladiatus (1) google (1) Google Maps API (2) grep (1) Grub (1) HR (2) html (23) HTS (8) IE (1) IE 8 (1) IIS (1) IMAP (3) Internet Explorer (1) java (3) JavaScript (22) jQuery (6) JSON (1) K3b (1) LED (3) Linux (112) Linux Mint (4) Load Balance (1) Microsoft (2) MIS (2) MM (51) MSSQL (1) MySQL (27) Network (1) NFS (1) Office (1) Oracle (125) Outlook (3) PDF (6) Perl (59) PHP (33) PL/SQL (1) PL/SQL Developer (1) PM (3) Postfix (2) postfwd (1) PostgreSQL (1) PP (50) python (1) QM (1) Red Hat (4) Reporting Service (28) ruby (11) SAP (234) scp (1) SD (16) sed (1) Selenium-WebDriver (5) shell (5) SQL (4) SQL server (8) SQuirreL SQL Client (1) SSH (2) SWOT (3) Symantec (2) T-SQL (7) Tera Term (2) tip (1) tiptop (22) Tomcat (6) Trouble Shooting (1) Tuning (5) Ubuntu (33) ufw (1) utf-8 (1) VIM (11) Virtual Machine (2) vnc (3) Web Service (2) wget (1) Windows (19) Windows (1) WM (6) youtube (1) yum (2)

2014年5月14日 星期三

MySQL 的 "SET NAMES xxx" 字元編碼問題分析

http://www.vixual.net/blog/archives/310

[轉載]MySQL 的 "SET NAMES xxx" 字元編碼問題分析

轉載自: PHPChina

近來接受 BBT 的培訓,做一個投票系統。系統程式碼倒不是很難,但是我的時間主要花費在了研究字符集和編碼上面。MySQL 和 Apache 兩個系統的編碼(字符集)問題讓我費勁腦筋,吃盡苦頭。網上對這些問題的解決比較零散,比較片面,大部分是提供解決方法,卻不說為什麼。於是我將這幾天收 穫總結一下,避免後來者再走彎路。這篇文章對 PHP 編寫有一點幫助(看完你就知道,怎樣讓你的 PHP 程式在大部分空間提供商的伺服器裡顯示正常),但是更多幫助在於網路伺服器的架設和設置。

先說 MySQL 的字符集問題。Windows 下可透過修改 my.ini 內的
# CLIENT SECTION
[mysql]
default-character-set=utf8
# SERVER SECTION
[mysqld]
default-character-set=utf8
這兩個字段來更改資料庫的預設字符集。第一個是客戶端預設的字符集,第二個是伺服器端預設的字符集。假設我們把兩個都設為 utf8,然後在MySQL Command Line 裡面輸入 “show variables like 'character%';”,可看到如下結果:
character_set_client   latin1
character_set_connection    latin1
character_set_database     utf8
character_set_results    latin1
character_set_server   utf8
character_set_system     utf8
其中的 utf8 隨著我們上面的設置而改動。此時,要是我們透過採用 UTF-8 的 PHP 程式從資料庫裡讀取資料,很有可能是一串 “?????” 或者是其他亂碼。網上查了半天,解決辦法倒是簡單,在連結資料庫之後,讀取資料之前,先執行一項查詢 “SET NAMES UTF8″,即在 PHP 裡為
mysql_query("SET NAMES UTF8");
即可顯示正常(只要資料庫裡資料的字元正常)。為什麼會這樣?這句查詢 “SET NAMES UTF8″ 到底是什麼作用?
到 MySQL 命令行輸入 “SET NAMES UTF8;”,然後執行 “show variables like 'character%';”,發現原來為 latin1 的那些變數 “character_set_client”、”character_set_connection”、 ”character_set_results” 的值全部變為 utf8 了,原來是這 3 個變數在搗蛋。
查閱手冊,上面那句等於:
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
看看這 3 個變數的作用:
資料輸入路徑:client → connection → server;
資料輸出路徑:server → connection → results。
換句話說,每個路徑要經過 3 次改變字符集編碼。以出現亂碼的輸出為例,server 裡 utf8 的資料,傳入 connection 轉為 latin1,傳入 results 轉為 latin1,utf-8 頁面又把 results 轉過來。如果兩種字符集不相容,比如 latin1 和 utf8,轉化過程就為不可逆的,破壞性的。所以就轉不回來了。
但這裡要聲明一點,”SET NAMES UTF8″ 作用只是臨時的,MySQL 重啟後就恢復預設了。
接下來就說到 MySQL 在伺服器上的配置問題了。豈不是我們每次對資料庫讀寫都得加上 “SET NAMES UTF8″,以保證資料傳輸的編碼一致?能不能透過配置 MySQL 來達到那三個變數預設就為我們要想的字符集?手冊上沒說,我在網上也沒找到答案。所以,從伺服器配置的角度而言,是沒辦法省略掉那行程式碼的。
總結:為了讓你的網頁能在更多的伺服器上正常地顯示,還是加上 “SET NAMES UTF8″ 吧,即使你現在沒有加上這句也能正常瀏覽。
問題多多,多謝指正!

參考網頁

  1. PHPChina: Apache和PHP網頁的編碼問題分析
  2. MySQL: Character Set Support

沒有留言:

張貼留言