MySQL 4.1 引入多層級字元集設定(伺服器、資料庫、資料表、欄位),但許多 PHP 程式(如 WordPress)未區分版本差異,且預設字元集 latin1 掩蓋了中文環境下的問題。
character_set_server(預設 latin1,安裝常改為 utf8)。character_set_server → character_set_database。character_set_client(發送編碼),MySQL 先轉為 character_set_connection,再轉為資料庫預設編碼儲存(兩次轉換)。character_set_results 輸出給客戶端。client=latin1, connection=latin1,導致「UTF-8 被當 latin1 轉 latin1 再轉 utf8」,字元遺失變 ??。results=latin1 反而正常顯示,但實際儲存為亂碼,遷移極其危險。SET NAMES 'utf8' 等同於:
SET character_set_client = 'utf8';
SET character_set_connection = 'utf8';
SET character_set_results = 'utf8';
若客戶端送 GB2312,可設:
SET character_set_client = 'gb2312';
SET character_set_connection = 'utf8'; -- 或 gb2312
SET character_set_results = 'gb2312';
在 wp-includes/wp-db.php 加入:
function set_charset($charset) {
$serverVersion = mysql_get_server_info($this->dbh);
$version = explode('.', $serverVersion);
if ($version[0] < 4) return;
$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 載入變數後呼叫:
$wpdb->set_charset(get_bloginfo('charset'));
僅連線時執行一次,避免每查詢重複設定。
掌握字元集傳遞鏈路,連線建立即執行 SET NAMES,即可徹底解決 MySQL 4.1+ 環境下的中文亂碼問題。