中文亂碼注意事項:
1:APACHE伺服器設定導緻亂碼
2:PHP,或者HTML頁面編碼導緻中文亂碼
3:MYSQL資料庫的表以及字段編碼導緻中文亂碼
了解一些基本理論:
1、檔案編碼
每個檔案在儲存的時候都可以選擇以什麼編碼儲存,例如用WINDOWS的記事本建立一個檔案可以選擇ANSI 以及UTF8等等編碼。我們選擇了什麼編碼該檔案就以這種編碼方式儲存在硬碟上。 讀取該檔案資料的時候也會指定一種編碼來打開,如果指定的編碼與檔案儲存的時候的編碼不一樣的話就會出現亂碼
2、HTML的編碼
在網頁頭部一般有這樣一個<HEAD>區域
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
這個的意思是讓用戶端知道,接下來輸出的是html代碼(text/html),并且以下輸出的内容都将是utf-8編碼的。如果我們用記事本建立一個HTML檔案 該檔案包含
但是在儲存的時候卻以ANSI編碼格式儲存,那麼我們用浏覽器打開這個檔案時,浏覽器看見META 行的UTF8編碼設定後 就将檔案以UTF8格式輸出,而檔案本來是ANSI編碼,這樣便出現了中文亂碼。
一:APACHE伺服器編碼
在APACHE配置檔案中有一行是編碼的設定 預設的是AddDefaultCharset ISO-8859-1,大部分人認為應該将這句改為 AddDefaultCharset UTF-8 。而蝸牛認為這是誤人子弟。 這項配置是告訴APACHE伺服器選用什麼樣的編碼來輸出WEB頁面(這樣做會忽略,HTML頁面中的頁面編碼的設定 EG:<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />),如果我們建立一個GB2312的頁面就會出現中文亂碼 。是以最好的方法是将AddDefaultCharset ISO-8859-1這一項注釋掉 #AddDefaultCharset
修改httpd.conf
查找:
AddDefaultCharset ISO-8859-1
改成:
#AddDefaultCharset ISO-8859-1
AddDefaultCharset off
二:PHP編碼問題
php最終生成的是文本檔案,而他要從資料庫中取出文本資料,還要把文本資料寫到資料庫中。由于MYSQL并不知道PHP發送給他的是什麼編碼的資料,是以需要用戶端PHP告訴他存取的是什麼編碼的資料。然後MYSQL會自動将PHP傳送來的資料轉換成目标編碼格式的資料。
比如: PHP要将 文本資料DATE 寫入到資料庫字段field中,PHP發送的是UTF-8編碼的資料,而DATE是以GB2312方式存儲的。這時候PHP通過設定告訴MYSQL 我發的是UTF-8格式,MYSQL接到資料後 說:”我知道了,來誰專門負責将UTF-8轉換成GB2312“ 于是MYSQL中的一個專門負責此事的小兵跑來 把資料拿走經過加工放到指定位置,如果PHP誤将UTF-8編碼的資料 當作GB2312編碼 送給MYSQL的時候,MYSQL會叫上次那個負責UTF-8—-GB2312的小兵來負責,而小兵不管三七二十一按同樣方法轉換存起來,這就出現了錯誤,亂碼就産生了。取資料的時候也一樣,PHP要告訴MYSQL要取出什麼樣編碼的資料。
PHP通過character_set_client告訴MYSQL,php存入資料庫的是什麼編碼方式
PHP通過character_set_results告訴MYSQL,php需要取什麼樣編碼的資料
PHP通過character_set_connection告訴MYSQL,PHP查詢中的文本,使用什麼編碼
就算上面的大家都注意了,還有個問題也可能導緻亂碼。那就是PHP檔案(生成的HTML頁面)本身的編碼問題
如果MYSQL傳來的資料 編碼與PHP本身編碼不一緻也會導緻亂碼
修改php.ini檔案将default_charset = "utf8"
三:MYSQL編碼問題
Mysql目前支援多字元集,并且,支援在不同的字元集之間轉換(便于移植和支援多語言)。
Mysql可以設定伺服器級字元集、資料庫級字元集、資料表級字元集、表列的字元集,實際上,最終使用字元集的地方是存儲字元的列,比如,你設定 table1中col1列是字元類型,col1才用到了字元集,如果table1表的col2列是int類型,col2不使用字元集的概念。
伺服器級字元集、資料庫級字元集、資料表級字元集都是為列的字元集做預設選項的。
Mysql一定有一個字元集,可以通過啟動時加參數指定 ,也可以編譯時指定,也可以在配置檔案裡指定。Mysql伺服器字元集,隻是做為資料庫級的預設值。建立資料庫時,你可以指定字元集,如果沒指定,就使用伺服器的字元集。同理,建立表時,你可以指定表級的字元集,如果沒指定,使用資料庫的字元集做為表的字元集。建立列時,你可以指定某列的字元集,如果沒指定,就使用表的字元集。
通常情況下,您隻需設定伺服器級的字元集,其它的資料庫級,表級,以及列級的字元集,都繼承自伺服器級字元集。
由于UTF8是最廣的字元集,是以,一般情況下,我們設定Mysql伺服器級的字元集為UTF8!
>show variables like 'character%'; 執行編碼顯示
| Variable_name | Value |
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/
在某些時候,我們續要修改mysql預設資料庫的編碼,以保證某些遷移的程式可以正常顯示,編輯my.cnf檔案進行編碼修改,windows可以直接用Mysql Server Instance Config Wizard 進行設定
在linux下修改3個my.cnf的1個/etc/mysql/my.cnf檔案
找到用戶端配置[client] 在下面添加
default-character-set=utf8 預設字元集為utf8
在找到[mysqld] 添加
init_connect='SET NAMES utf8' (設定連接配接mysql資料庫時使用utf8編碼,以讓mysql資料庫為utf8運作)
修改好後,重新啟動mysql 即可,查詢一下
show variables like 'character%';
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
總結:
要保證不亂碼,需将三個編碼統一:
一:是網頁自身的編碼
二:是HTML裡指定的編碼
三:是PHP告訴Mysql的編碼(包括character_set_client和character_set_results)。
第一和第二個編碼,如果使用DW之類的編輯器寫的網頁,通常是一緻的,但用記事本寫的網頁,有可能不一緻。
第三個編碼,需要手工通知Mysql。這步可以通過在PHP裡使用mysql_query(“set names characterX”)來實作。