朱海巖
(呂梁學(xué)院汾陽(yáng)師范分校,山西 汾陽(yáng) 032200)
PHP與MySQL Web應(yīng)用平臺(tái)中文亂碼問(wèn)題研究
朱海巖
(呂梁學(xué)院汾陽(yáng)師范分校,山西 汾陽(yáng) 032200)
在運(yùn)用PHP和MySQL平臺(tái)進(jìn)行Web應(yīng)用程序開發(fā)時(shí),經(jīng)常會(huì)在處理中文信息過(guò)程中出現(xiàn)亂碼.本文就亂碼產(chǎn)生的原因進(jìn)行了深入地分析和討論,并提出了徹底解決亂碼問(wèn)題的方法.
亂碼;字符集;MySQL
PHP和MySQL以其開源、免費(fèi)、高性能等眾多優(yōu)勢(shì),在Web應(yīng)用領(lǐng)域占領(lǐng)了越來(lái)越多的市場(chǎng)份額.現(xiàn)在,PHP與MySQL的主流版本已經(jīng)能夠完全兼容中文信息,但是在進(jìn)行中文應(yīng)用程序開發(fā)的過(guò)程中會(huì)經(jīng)常出現(xiàn)一些亂碼問(wèn)題.究其原因,是因?yàn)橛?jì)算機(jī)中漢字的編碼方式不統(tǒng)一.同一個(gè)漢字在不同字符集中的編碼是不一樣的,如果一些應(yīng)用程序默認(rèn)采用了不同的字符集又缺乏合理的轉(zhuǎn)換機(jī)制,在相互通信中就極有可能出現(xiàn)中文亂碼.
GB2312-80也稱GB2312是漢字字符集和編碼的代號(hào),是最基本的漢字編碼集.中文全稱為“信息交換用漢字編碼字符集”,1980年,由中華人民共和國(guó)國(guó)家標(biāo)準(zhǔn)總局發(fā)布,1981年5月1日起實(shí)施.
GB2312字符集只收錄簡(jiǎn)化漢字,以及常用字母和符號(hào),共收錄有7445個(gè)字符,其中簡(jiǎn)化漢字6763個(gè),字母和符號(hào)682個(gè).在大陸及海外使用簡(jiǎn)體中文的地區(qū)(如新加坡等)是使用最廣泛的中文編碼.該標(biāo)準(zhǔn)的制定和應(yīng)用為規(guī)范、推動(dòng)中文信息化進(jìn)程起了很大作用,其最大的特點(diǎn)是只支持簡(jiǎn)體中文.
GBK全名為“漢字內(nèi)碼擴(kuò)展規(guī)范”,即GB2312-80的擴(kuò)展字符集.
1993年,Unicode 1.1版本推出,收錄了中國(guó)大陸、臺(tái)灣、日本及韓國(guó)通用字符集的漢字,總共有20,902個(gè).隨后,中國(guó)大陸訂定了等同于Unicode 1.1版本的GB 13000.1-93.
由于GB 2312-80只收錄了6763個(gè)漢字,有不少簡(jiǎn)體漢字以及臺(tái)灣和香港地區(qū)使用的繁體字,日語(yǔ)及朝鮮語(yǔ)漢字等,并未有收錄在內(nèi).于是,一些軟件開發(fā)商利用了GB 2312-80未使用的編碼空間,收錄了所有出現(xiàn)在Unicode 1.1及GB 13000.1-93之中的漢字,制定了GBK編碼.雖然GBK收錄了所有Unicode 1.1及GB 13000.1-93之中的漢字,但是編碼方式與Unicode 1.1及GB 13000.1-93不同.
UTF-8(8-bit Unicode Transformation Format)是一種針對(duì)Unicode的可變長(zhǎng)度字符編碼,也是一種前綴碼.它可以用來(lái)表示Unicode標(biāo)準(zhǔn)中的任何字符,且其編碼中的第一個(gè)字節(jié)仍與ASCII兼容,這使得原來(lái)處理ASCII字符的軟件無(wú)須或只須做少部份修改,即可繼續(xù)使用.因此,它逐漸成為電子郵件、網(wǎng)頁(yè)及其他存儲(chǔ)或傳送文字的應(yīng)用中,優(yōu)先采用的編碼.
總之,以上幾種字符集都能支持中文,但又有所不同.GB2312-80只能支持中文簡(jiǎn)體,GBK是GB2312-80的超集,支持中文簡(jiǎn)體、繁體以及日文、韓文符號(hào).UTF-8是一種更通用的字符集,支持世界各種語(yǔ)言的符號(hào).如果某個(gè)Web應(yīng)用程序只是針對(duì)國(guó)內(nèi)用戶,可以考慮采用GB2312-80字符集,GBK是一種非官方標(biāo)準(zhǔn)的字符集,有時(shí)還是會(huì)有些問(wèn)題.如果考慮到該Web應(yīng)用有可能面對(duì)國(guó)際用戶或者是為了取得更好的兼容性,則應(yīng)該使用UTF-8字符集.
● character_set_server:服務(wù)器字符集,用來(lái)為create database命令提供默認(rèn)值.
● character_set_database:當(dāng)前數(shù)據(jù)庫(kù)的字符集,為create table命令提供默認(rèn)值.
● character_set_table:當(dāng)前數(shù)據(jù)表的字符集,為列的字符集提供默認(rèn)值.
● character_set_client:客戶端默認(rèn)字符集,當(dāng)服務(wù)器接收到客戶端發(fā)來(lái)的數(shù)據(jù)時(shí),按些字符集進(jìn)行解碼.
● character_set_results:結(jié)果字符集,當(dāng)服務(wù)器向客戶端返回查詢結(jié)果時(shí),以此字符集規(guī)則進(jìn)行編碼.
● character_set_connection:連接字符集,這個(gè)變量用來(lái)決定MySQL怎么處理客戶端發(fā)來(lái)的SQL命令.MySQL會(huì)把SQL命令從character_set_client編碼轉(zhuǎn)到character_set_connection編碼,然后再執(zhí)行.
假設(shè)客戶端(即為PHP頁(yè)面端)采用UTF-8字符集.
1>客戶端向服務(wù)器端(即MySQL)發(fā)送數(shù)據(jù),這些數(shù)據(jù)根據(jù)假設(shè)以UTF-8字符集編碼.
2>服務(wù)器端收到客戶端發(fā)來(lái)的數(shù)據(jù),以character_set_client(假設(shè)其值為latin1)規(guī)定的編碼方式進(jìn)行解碼.
3>服務(wù)器端處理完客戶端的查詢請(qǐng)求,準(zhǔn)備好數(shù)據(jù),以character_set_result(假設(shè)其值為latin1)形式編碼并發(fā)送到客戶端.
4>客戶端接收到服務(wù)器端發(fā)來(lái)的數(shù)據(jù),并以自己的編碼形式(第1>步假定為UTF-8)進(jìn)行解碼.
第1>步向服務(wù)器發(fā)送了一組UTF-8編碼的數(shù)據(jù),但服務(wù)器端以latin1字符集規(guī)則進(jìn)行解碼,則不能還原數(shù)據(jù),所以存儲(chǔ)到數(shù)據(jù)庫(kù)中的內(nèi)容會(huì)顯示成亂碼.
第4>步服務(wù)器端向客戶端發(fā)送了latin1編碼形式的數(shù)據(jù),但客戶端以UTF-8形式解碼,則顯示在頁(yè)面上的內(nèi)容也是亂碼.
客戶端向服務(wù)器端發(fā)送正確命令而服務(wù)器端不能正確識(shí)別也是由于類似原因.
綜上所述,產(chǎn)生亂碼問(wèn)題的原因可以總結(jié)如表1:
表1
所以,將服務(wù)器端的character_set_client、character_set_connection、character_set_results三個(gè)系統(tǒng)變量的值設(shè)置為客戶端所采用的字符集,則可以從根本上解決中文亂碼問(wèn)題.
一般情況下,html的head部分會(huì)有如下代碼:
此行代碼指定了本頁(yè)面的字符使用UTF-8字符集編碼.
如果是純PHP文件,不包含html代碼,也可以使用以下代碼指定該頁(yè)面的字符集:
header(“content-type:text/html;charset=utf-8”);
以上兩處代碼中的utf-8可以修改成任意合法的字符集.
1>修改MySQL配置文件
在MySQL的安裝目錄下找到其配置文件my.ini,分別在 [mysqld]與 [mysql]下添加代碼”default-character-set=utf8”.
保存my.ini并重新啟動(dòng)MySQL服務(wù),會(huì)發(fā)現(xiàn)系統(tǒng)變量的值均被改為utf8.
2>在客戶端動(dòng)態(tài)改變MySQL系統(tǒng)變量
由于大多數(shù)的用戶只是租用虛擬主機(jī)運(yùn)營(yíng)網(wǎng)站,因此根本無(wú)權(quán)修改MySQL的配置文件.而且一般情況下程序員也不知道將來(lái)代碼會(huì)放到什么樣的服務(wù)器環(huán)境下運(yùn)行,因此在客戶端與服務(wù)器端建立連接以后,動(dòng)態(tài)修改服務(wù)器端相關(guān)系統(tǒng)變量的值,是一種更通用和可靠的辦法.具體代碼如下:
PHP與MySQL Web應(yīng)用平臺(tái)下產(chǎn)生中文亂碼的根本原因在于字符集編碼方式的不統(tǒng)一.只要約定采用統(tǒng)一的字符集或者控制不同字符集之間正確轉(zhuǎn)換,則可以從根本上解決該平臺(tái)下的中文亂碼問(wèn)題.
〔1〕Luke Welling、Laura Thomson, 武欣譯.PHP 和MySQL Web開發(fā)[M].北京:機(jī)械工業(yè)出版社,2009.
〔2〕姜承堯.MySQL技術(shù)內(nèi)幕:InnoDB存儲(chǔ)引擎[M].北京:機(jī)械工業(yè)出版社,2011.
〔3〕Charles A.Bell,楊濤、王建橋、楊曉云等譯.深入理解MySQL[M].北京:人民郵電出版社,2010.
〔4〕W.Jason Gilmori,朱濤江譯.PHP 與 MySQL 程序設(shè)計(jì)[M].北京:人民郵電出版社,2007.
TP391.1
A
1673-260X(2011)08-0036-02