MySQL字符集編碼設置與PHP顯示亂碼的解決辦法

文本編碼

Linux默認文本編碼是Unicode編碼(UTF-8和UTF-16),
簡體中文Windows的默認文本編碼是國標碼(GB2312和GB18030),
所以打開windows下的文本文件通常會亂碼。
以KWrite爲例,打開windows下的xx.txt,
如果亂碼了,選擇KWrite的菜單
“工具”---->“編碼”---->“簡體中文”---->“GB18030”
然後顯示簡體中文就正常了。
如果要讓編輯器默認就打開GB18030的文本,
選擇菜單
“設置”---->“配置編輯器”,打開設置對話框,
在對話框左邊一欄選“打開和保存”,
右邊會看到“通用”項,裏面“文件格式”---->“編碼”,
從列表裏選擇“簡體中文GB18030”,保存配置。

然後點擊xx.txt,默認就是國標碼打開,不會亂碼了。


PHP顯示MySQL查詢結果時顯示亂碼對於新手在實際編程中是經常會遇到的問題,我們在接下來的文章中將會爲大傢俱體介紹PMySQL字符集編碼設置與PHP顯示亂碼的解決辦法,希望對有需要的朋友們有所幫助。


從亂碼產生的原因來分析,亂碼的產生一般有以下幾種情況。


1、網頁編碼與程序編碼不一致的問題


所謂的網頁編碼問題就是指你的html代碼中定義的“charset”,例如以下這段代碼:


<head>
<title>Chat Tutorial Application</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="language" content="en" />
</head>
它設置了瀏覽器端採用gb2312的字符集,此時如果程序使用的是utf8的編碼(就是指以什麼樣的編碼來編寫的程序,一般在編輯器中設置),那麼就會產生亂碼。


此時的解決方法就是把charset的值改爲UTF-8。


2、代碼本身就存在亂碼問題


這種情況是指你的代碼本身就存在亂碼問題。照成這種情況的原因一般是你以另一種編碼格式修改了你的代碼後並做了保存,這樣你的程序中就有幾種編碼形式的代碼,那麼輸出的時候自然就會有亂碼。這類問題相對來說比較容易解決,只要人工找到那段有亂碼的代碼,然後修改就行了(很多編輯器可以完成這個工作)。


3、mysql的問題(此次討論僅圍繞mysql5.0之後的版本展開)


現在再來看最容易照成亂碼,也是最容易讓人迷糊的mysql亂碼問題。


要說mysql亂碼,得先從mysql的幾個參數說起,從mysql5開始,多了幾個設置字符集的系統變量:


character_set_client  客戶端字符集
character_set_connection 客戶端與服務器端連接採用的字符集
character_set_results  SELECT查詢返回數據的字符集
character_set_database 數據庫採用的字符集
亂碼問題一般是由於以上幾個變量設置錯誤照成的,很多人在請教亂碼問題的時候,一般都會得到一個這樣的答案:“你先set names一下”。


那麼set names是什麼呢? set names實際上就是同時設置了character_set_client,character_set_connection,character_set_results這三個系統變量。


例如set names 'utf8'等同於:

set @@character_set_client = 'utf8'
set @@character_set_connection = 'utf8'
set @@character_set_results = 'utf8'


很多情況下,在連接數據庫之後,讀取數據之前,先執行一項查詢“SET NAMES UTF8”,即在PHP裏爲:


 mysql_query("SET NAMES UTF8");


即可顯示正常(只要數據庫裏信息的字符正常)。這樣設置了之後就能把亂碼問題解決了。
但是還是不能完全避免出現亂碼的可能,爲什麼呢?


因爲character_set_client,character_set_connection這兩個變量僅用與保證與character_set_database編碼的一致,而character_set_results則用與保證SELECT返回的結果與程序的編碼一致。


例如,你的數據庫(character_set_database)用的是utf8的字符集,那麼你就要保證character_set_client,character_set_connection也是utf8的字符集。而你的程序也許採用的並不是utf8,比如你的程序用的是gbk,那麼你若把character_set_results也設置爲utf8的話就會出現亂碼問題。此時你應該把character_set_results設置爲gbk。這樣就能保證數據庫返回的結果與你的程序的編碼一致。


下面我給出一段用於設置字符集的代碼(其中用到了一個我自己寫的db庫,相信應該不影響閱讀):


<?
//假設我們的程序採用的是utf8的字符集
$program_char = 'utf8';
//先檢查mysql的版本號,如果版本號大於4我們纔可以設置這些系統變量(mysql4還沒有這些系統變量)
$version = current($db->fetch_one('SELECT VERSION()'));
if (substr($version, 0, 1) > 4)
{
//取出當前數據庫的字符集
$sql = 'SELECT @@character_set_database';
$char = current($db->fetch_one($sql));
//將客戶端字符集(character_set_client)和
連接字符集(character_set_connection)設置爲與數據庫字符集(character_set_database)一致
$db->query('SET @@character_set_client = "' . $char . '"');
$db->query('SET @@character_set_connection = "' . $char . '"');
//將SELECT查詢返回數據的字符集設置爲與當前程序的字符集一致
$db->query('SET @@character_set_results = "' . $program_char . '"');
}
?>
到此應該就可以解決絕大多數我們遇到的亂碼問題了,另外還必須強調的是,有時候亂碼的出現有可能是以上幾種原因混合造成的。


對於這樣的問題處理起來就比較的麻煩。因爲首先要保證你在數據庫中保存的數據的字符集與數據庫的字符集是一致的。如果你在一個utf8的數據庫中保存了GBK字符數據(如果你頁面的編碼與數據庫的編碼不一致,那麼產生這個問題的可能性就很大),那麼假設以上的設置都正確,結果還是會出現亂碼的問題。不過這類問題一旦確定了產生的原因,那麼就還是有辦法解決的,比如剛纔我舉的這個例子。


我們如果能確保其他環節的設置都是正確的,並且能夠確認是由於把gbk的數據存到了utf8的數據庫中而造成的亂碼,那麼我就可以把這些數據從數據庫中取出來之後再用iconv()轉換編碼也是可以的。
總而言之,我們應當儘量的保證數據庫中的數據是正確的,那麼問題處理起來就相對簡單了。


說了一大堆可能把你給弄迷糊了,我將其總結爲以下四點,便於大家記憶。


1、要保證數據庫中存的數據與數據庫編碼一致,即數據編碼與character_set_database一致;


2、要保證通訊的字符集與數據庫的字符集一致,即character_set_client, character_set_connection與character_set_database一致;


3、要保證SELECT的返回與程序的編碼一致,即character_set_results與程序編碼一致;


4、要保證程序編碼與瀏覽器編碼一致,即程序編碼與<meta http-equiv="Content-Type" content="text/html; charset=?"/>一致。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章