天天看點

中文亂碼

中文亂碼注意事項:

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”)來實作。

繼續閱讀