最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL中文亂碼問題的解決第1/2頁

 更新時(shí)間:2006年12月11日 00:00:00   作者:  
轉(zhuǎn)自:http://www.phpchina.cn/viewarticle.php?id=1584


下面要寫的是一篇非常無聊的東西,充斥了大量各式各樣的編碼、轉(zhuǎn)換、客戶端、服務(wù)器端、連接……呃,我自己都不愿意去看它,但想一想,寫下來還是有點(diǎn)意義的,原因有四:

MySQL 4.1 對多語言的支持有了很大變化 (這導(dǎo)致了問題的出現(xiàn));
盡管大部分的地方 (包括個(gè)人使用和主機(jī)提供商),MySQL 3 仍然占主導(dǎo)地位;但 MySQL 4.1 是 MySQL 官方推薦的數(shù)據(jù)庫,已經(jīng)有主機(jī)提供商開始提供并將會越來越多;
許多 PHP 程序以 MySQL 作為默認(rèn)的數(shù)據(jù)庫管理軟件,但它們一般不區(qū)分 MySQL 4.1 與 4.1 以下版本的區(qū)別,籠統(tǒng)地稱“MySQL 3.xx.xx 以上版本”就滿足安裝需求了;
因?yàn)?latin1 在許多地方 (下邊會詳細(xì)描述具體是哪些地方) 作為默認(rèn)的字符集,成功的蒙蔽了許多 PHP 程序的開發(fā)者和用戶,掩蓋了在中文等語言環(huán)境下會出現(xiàn)的問題;
簡單的說,MySQL 自身的變化和使用 MySQL 的 PHP 程序?qū)Υ撕雎裕瑢?dǎo)致了問題的出現(xiàn)和復(fù)雜化,而由于大部分用戶使用的是英文,使這種問題不被重視。這里提到的 PHP 程序,主要就 WordPress 而言。

MySQL 4.1 字符集支持的原理MySQL 4.1 對于字符集的指定可以細(xì)化到一臺機(jī)器上安裝的 MySQL,其中的一個(gè)數(shù)據(jù)庫,其中的一張表,其中的一欄,應(yīng)該用什么字符集。但是,傳統(tǒng)的 Web 程序在創(chuàng)建數(shù)據(jù)庫和數(shù)據(jù)表時(shí)并沒有使用那么復(fù)雜的配置,它們用的是默認(rèn)的配置,那么,默認(rèn)的配置從何而來呢?

編譯 MySQL 時(shí),指定了一個(gè)默認(rèn)的字符集,這個(gè)字符集是 latin1;
安裝 MySQL 時(shí),可以在配置文件 (my.ini) 中指定一個(gè)默認(rèn)的的字符集,如果沒指定,這個(gè)值繼承自編譯時(shí)指定的;
啟動(dòng) mysqld 時(shí),可以在命令行參數(shù)中指定一個(gè)默認(rèn)的的字符集,如果沒指定,這個(gè)值繼承自配置文件中的;
此時(shí) character_set_server 被設(shè)定為這個(gè)默認(rèn)的字符集;
當(dāng)創(chuàng)建一個(gè)新的數(shù)據(jù)庫時(shí),除非明確指定,這個(gè)數(shù)據(jù)庫的字符集被缺省設(shè)定為 character_set_server;
當(dāng)選定了一個(gè)數(shù)據(jù)庫時(shí),character_set_database 被設(shè)定為這個(gè)數(shù)據(jù)庫默認(rèn)的字符集;
在這個(gè)數(shù)據(jù)庫里創(chuàng)建一張表時(shí),表默認(rèn)的字符集被設(shè)定為 character_set_database,也就是這個(gè)數(shù)據(jù)庫默認(rèn)的字符集;
當(dāng)在表內(nèi)設(shè)置一欄時(shí),除非明確指定,否則此欄缺省的字符集就是表默認(rèn)的字符集;
這個(gè)字符集就是數(shù)據(jù)庫中實(shí)際存儲數(shù)據(jù)采用的字符集,mysqldump 出來的內(nèi)容就是這個(gè)字符集下的;

簡單的總結(jié)一下,如果什么地方都不修改,那么所有的數(shù)據(jù)庫的所有表的所有欄位的都用 latin1 存儲,不過我們?nèi)绻惭b MySQL,一般都會選擇多語言支持,也就是說,安裝程序會自動(dòng)在配置文件中把 default_character_set 設(shè)置為 UTF-8,這保證了缺省情況下,所有的數(shù)據(jù)庫的所有表的所有欄位的都用 UTF-8 存儲。

當(dāng)一個(gè) PHP 程序與 MySQL 建立連接后,這個(gè)程序發(fā)送給 MySQL 的數(shù)據(jù)采用的是什么字符集?MySQL 無從得知 (它最多只能猜測),所以 MySQL 4.1 要求客戶端必須指定這個(gè)字符集,也就是 character_set_client,MySQL 的怪異之處在于,得到的這個(gè)字符集并不立即轉(zhuǎn)換為存儲在數(shù)據(jù)庫中的那個(gè)字符集,而是先轉(zhuǎn)換為 character_set_connection 變量指定的一個(gè)字符集;這個(gè) connection 層究竟有什么用我不大明白,但轉(zhuǎn)換為 character_set_connection 的這個(gè)字符集之后,還要轉(zhuǎn)換為數(shù)據(jù)庫默認(rèn)的字符集,也就是說要經(jīng)過兩次轉(zhuǎn)換;當(dāng)這個(gè)數(shù)據(jù)被輸出時(shí),又要由數(shù)據(jù)庫默認(rèn)的字符集轉(zhuǎn)換為 character_set_results 指定的字符集。

一個(gè)典型的環(huán)境典型的環(huán)境以我自己的電腦上安裝的 MySQL 4.1 為例,我自己的電腦上安裝著 Apache 2,PHP 5 和 WordPress 1.5.1.3,MySQL 配置文件中指定了 default_character_set 為 utf8。于是問題出現(xiàn)了:

WordPress 按照默認(rèn)情況安裝,所以所有的表都用 UTF-8 存儲數(shù)據(jù);
WordPress 默認(rèn)采用的瀏覽字符集是 UTF-8 (Options->Reading 中設(shè)置),因此所有 WP 頁面的 meta 中會說明 charset 是 utf-8;
所以瀏覽器會以 utf-8 方式顯示所有的 WP 頁面;這樣一來 Write 的所有 Post,和 Comment 都會以 UTF-8 格式從瀏覽器發(fā)送給 Apache,再由 Apache 交給 PHP;
所以 WP 從所有的表單中得到的數(shù)據(jù)都是 utf-8 編碼的;WP 不加轉(zhuǎn)換的直接把這些數(shù)據(jù)發(fā)送給 MySQL;
MySQL 默認(rèn)設(shè)置的 character_set_client 和 character_set_connection 都是 latin1,此時(shí)怪異的事情發(fā)生了,實(shí)際上是 utf-8 格式的數(shù)據(jù),被“當(dāng)作 latin1”轉(zhuǎn)換成……居然還是轉(zhuǎn)換成 latin1,然后再由這個(gè) latin1 轉(zhuǎn)換成 utf-8,這么兩次轉(zhuǎn)換,有一部分 utf-8 的字符就丟失了,變成 ??,最后輸出的時(shí)候 character_set_results 默認(rèn)是 latin1,也就輸出為奇怪的東西了。
最神奇的還不是這個(gè),如果 WordPress 中設(shè)置以 GB2312 格式閱讀,那么 WP 發(fā)送給 MySQL 的 GB2312 編碼的數(shù)據(jù),被“當(dāng)作 latin1”轉(zhuǎn)換后,存進(jìn)數(shù)據(jù)庫的是一種奇怪的格式 (真的是奇怪的格式,mysqldump 出來就能發(fā)現(xiàn),無論當(dāng)作 utf-8 還是當(dāng)作 gb2312 來讀都是亂碼),但如果這種格式以 latin1 輸出出來,居然又能變回 GB2312!

這會導(dǎo)致什么現(xiàn)象呢?WP 如果使用 MySQL 4.1 數(shù)據(jù)庫,把編碼改用 GB2312 就正常了,可惜,這種正常只是貌似正常。

如何解決問題如果你已經(jīng)不耐煩了 (幾乎是肯定的),google 一下,會發(fā)現(xiàn)絕大部分的解答是,query 之前先執(zhí)行一下:SET NAMES 'utf8',沒錯(cuò),這是解決方案,但本文的目的是說明,這為什么是解決方案。

要保證結(jié)果正確,必須保證數(shù)據(jù)表采用的格式是正確的,也就是說,至少能夠存放所有的漢字,那么我們只有兩種選擇,gbk 或者 utf-8,下面討論 utf-8 的情況。

因?yàn)榕渲梦募O(shè)置的 default_character_set 是 utf8,數(shù)據(jù)表默認(rèn)采用的就是 utf-8 建立的。這也應(yīng)該是所有采用 MySQL 4.1 的主機(jī)提供商應(yīng)該采用的配置。所以我們要保證的只是客戶端與 MySQL 交互之間指定編碼的正確。

這只有兩種可能,客戶端以 gb2312 格式發(fā)送數(shù)據(jù),或者以 utf-8 格式發(fā)送數(shù)據(jù)。

如果以 gb2312 格式發(fā)送:

SET character_set_client='gb2312'
SET character_set_connection='utf8' 或者
SET character_set_connection='gb2312'

都是可以的,都能夠保證數(shù)據(jù)在編碼轉(zhuǎn)換中不出現(xiàn)丟失,也就是保證存儲入數(shù)據(jù)庫的是正確的內(nèi)容。

怎么保證取出的是正確的內(nèi)容呢?考慮到絕大部分客戶端 (包括 WP),發(fā)送數(shù)據(jù)的編碼也就是它所希望收到數(shù)據(jù)的編碼,所以:

SET character_set_results='gb2312'

可以保證取出給瀏覽器顯示的格式就是 gb2312。

如果是第二種情況,客戶端以 utf-8 格式發(fā)送 (WP 的默認(rèn)情況),可以采用下述配置:

SET character_set_client='utf8'
SET character_set_connection='utf8'
SET character_set_results='utf8'

這個(gè)配置就等價(jià)于 SET NAMES 'utf8'。

WP 應(yīng)該作什么修改還是那句話,客戶端要發(fā)給數(shù)據(jù)庫什么編碼的數(shù)據(jù),數(shù)據(jù)庫是不可能確切知道的,只能讓客戶端自己說明白,所以,WP 是必須發(fā)送正確的 SET... 給 MySQL 的。怎么發(fā)送最合適呢?臺灣的 pLog 同仁給出了一些建議:

首先,測試服務(wù)器是否 >= 4.1,編譯時(shí)是否加入了 UTF-8 支持;是則繼續(xù)
然后測試數(shù)據(jù)庫以什么格式存儲 ($dbEncoding);
SET NAMES $dbEncoding
對于第二點(diǎn),WP 的情況是不同的,按照上面的典型配置,只要用 WP,肯定數(shù)據(jù)庫是用 UTF-8 存儲的,所以要根據(jù)用戶設(shè)置的以 GB2312 還是 UTF-8 瀏覽來判斷 (bloginfo('charset')),但這個(gè)值是要連接數(shù)據(jù)庫以后才能得到的,所以效率最高的方式是連接數(shù)據(jù)庫之后,根據(jù)這個(gè)配置設(shè)置一次 SET NAMES,而不必每次查詢之前都設(shè)置一遍。

我的修改方式是這樣的,在 wp_includes/wp-db.php 中增加:

function set_charset($charset)
{
// check mysql version first.
$serverVersion = mysql_get_server_info($this->dbh);
$version = explode('.', $serverVersion);
if ($version[0] < 4) return;

// check if utf8 support was compiled in
$result = mysql_query("SHOW CHARACTER SET like 'utf8'",
$this->dbh);
if (mysql_num_rows($result) < = 0) return;

if ($charset == 'utf-8' || $charset == 'UTF-8')
$charset = 'utf8';
@mysql_query("SET NAMES '$charset'", $this->dbh);
}

在 wp-settings.php 的 require (ABSPATH . WPINC . '/vars.php'); 后增加:

$wpdb->set_charset(get_bloginfo('charset'));

http://www.phpchina.cn/viewarticle.php?id=1584

相關(guān)文章

  • My Sql 1067錯(cuò)誤與編碼問題的解決方案

    My Sql 1067錯(cuò)誤與編碼問題的解決方案

    My Sql 大部分都是用綠色版(解壓版) 然后注冊服務(wù)簡單方便,但是配置文件也很讓人糾結(jié),下面小編給大家?guī)砹薓y Sql 1067錯(cuò)誤與編碼問題的解決方案,感興趣的朋友參考下吧
    2016-11-11
  • 強(qiáng)制修改mysql的root密碼的六種方法分享(mysql忘記密碼)

    強(qiáng)制修改mysql的root密碼的六種方法分享(mysql忘記密碼)

    下面我們提供了6種不同的修改mysql root用戶的密碼,與增加mysql用戶的方法
    2011-11-11
  • Mysql數(shù)據(jù)庫緩沖池詳解(Buffer pool)

    Mysql數(shù)據(jù)庫緩沖池詳解(Buffer pool)

    InnoDB存儲引擎通過BufferPool緩存數(shù)據(jù)頁和索引頁,減少磁盤I/O,提升查詢性能,BufferPool通過預(yù)讀和checkpoint機(jī)制優(yōu)化I/O操作和數(shù)據(jù)持久化
    2024-12-12
  • MySQL單表查詢實(shí)例詳解

    MySQL單表查詢實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于MySQL單表查詢的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 通過yum方式安裝mySql數(shù)據(jù)庫的全過程

    通過yum方式安裝mySql數(shù)據(jù)庫的全過程

    當(dāng)工作需要部署mysql時(shí),通過手動(dòng)上傳安裝包以及依賴包的方式安裝mysql會比較麻煩,可以添加官方y(tǒng)um源,來實(shí)現(xiàn)自動(dòng)安裝依賴,方便快捷,下面這篇文章主要給大家介紹了關(guān)于通過yum方式安裝mySql數(shù)據(jù)庫的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • MySQL Galera Cluster部署與使用

    MySQL Galera Cluster部署與使用

    MySQLGaleraCluster是一種高可用、同步復(fù)制的數(shù)據(jù)庫解決方案,本文主要介紹了MySQL Galera Cluster 部署與使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-03-03
  • CentOS7下 MySQL定時(shí)自動(dòng)備份的實(shí)現(xiàn)方法

    CentOS7下 MySQL定時(shí)自動(dòng)備份的實(shí)現(xiàn)方法

    這篇文章主要介紹了CentOS7 下MySQL定時(shí)自動(dòng)備份的實(shí)現(xiàn)方法,主要實(shí)現(xiàn)了數(shù)據(jù)庫備份,清理過期備份文件功能,需要的朋友可以參考下
    2019-12-12
  • mysql 8.0.22 winx64安裝配置方法圖文教程

    mysql 8.0.22 winx64安裝配置方法圖文教程

    這篇文章主要為大家詳細(xì)介紹了mysql8.0.22 winx64安裝配置方法圖文教程,文中安裝步驟介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • 詳解MySQL數(shù)據(jù)類型DECIMAL(N,M)中N和M分別表示的含義

    詳解MySQL數(shù)據(jù)類型DECIMAL(N,M)中N和M分別表示的含義

    關(guān)于MySQL數(shù)據(jù)類型decimal中n和m分別表示什么含義?本文就此問題作了簡單論述,并創(chuàng)建相關(guān)表進(jìn)行驗(yàn)證,需要的朋友可以了解下。
    2017-10-10
  • 在MySQL中使用子查詢和標(biāo)量子查詢的基本操作教程

    在MySQL中使用子查詢和標(biāo)量子查詢的基本操作教程

    這篇文章主要介紹了在MySQL中使用子查詢和標(biāo)量子查詢的基本操作教程,子查詢的使用時(shí)MySQL入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-12-12

最新評論

信丰县| 合水县| 保定市| 固始县| 康定县| 青岛市| 宜川县| 拉孜县| 花垣县| 武夷山市| 宁强县| 安远县| 区。| 上高县| 乌鲁木齐县| 日照市| 新津县| 台南市| 丰城市| 扬州市| 伊川县| 泽普县| 茶陵县| 滁州市| 青神县| 永胜县| 梁山县| 加查县| 保山市| 株洲县| 临夏县| 滁州市| 奎屯市| 南通市| 哈密市| 肇源县| 罗甸县| 横山县| 武宁县| 太谷县| 木里|