龐大站點從 GB2312/GBK 遷移至 UTF-8,前端代碼改造成本極高。需實現數據層 UTF-8 存儲、應用層 GBK 讀寫,最小化前端變更。
MySQL 支持客戶端連接字符集獨立於列存儲字符集:
前提:列定義 CHARACTER SET utf8 COLLATE utf8_general_ci,且入庫數據必須是合法 UTF-8。
CREATE TABLE `t` (
`id` INT(10) NOT NULL,
`name` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
INDEX (`g_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
class DB {
private $link, $db_name;
// 寫入/UTF-8 操作模式
function _select_db_utf() {
mysql_select_db($this->db_name, $this->link);
mysql_query("SET NAMES utf8", $this->link);
mysql_query("SET CHARACTER SET utf8", $this->link);
mysql_query("SET COLLATION_CONNECTION='utf8_general_ci'", $this->link);
return true;
}
// 讀取/GBK 輸出模式
function _select_db_gb() {
mysql_select_db($this->db_name, $this->link);
mysql_query("SET NAMES gbk", $this->link);
mysql_query("SET CHARACTER SET gbk", $this->link);
mysql_query("SET COLLATION_CONNECTION='gbk_chinese_ci'", $this->link);
return true;
}
# 業務代碼中:
# 寫入前調用 _select_db_utf()
# 讀取前調用 _select_db_gb()
}
現代寫法:使用 mysqli::set_charset('utf8') / PDO::MYSQL_ATTR_INIT_COMMAND,棄用 mysql_* 函數。
gbk、utf8 字符集(默認包含)。Content-Type: text/html; charset=gbk 與輸出編碼一致。| 函數 | 字符集覆蓋 | 自動識別 | 性能 | 典型用法 |
|---|---|---|---|---|
mb_convert_encoding | 最全 | 支持(指定列表) | 較慢 | mb_convert_encoding($str, 'UTF-8', 'GBK,GB2312,BIG5') |
iconv | 較少 | 需指定源編碼 | 較快 | iconv('GBK', 'UTF-8', $str) |
建議:明確源編碼用 iconv,不確定編碼用 mbstring。無完美自動識別方案,源頭規範編碼最關鍵。
iconv/mbstring 清洗導入。charset 聲明,最終全站 UTF-8。