舊系統採用 GBK/Big5,欲逐步遷移至 UTF-8,但前端頁面暫時仍需 GBK 輸出。MySQL 4.1+ 支援連線層字符集設定,可實現「儲存 UTF-8、讀取 GBK」無縫過渡。
CREATE TABLE `article` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`content` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
關鍵:表預設字符集 utf8(或 utf8mb4),欄位明確宣告 CHARACTER SET utf8 COLLATE utf8_general_ci。
封裝兩個方法,分別用於「寫入/更新」與「讀取/查詢」:
class MySQLiWrapper {
private $link;
private $dbName;
public function __construct($host, $user, $pass, $db) {
$this->link = mysqli_connect($host, $user, $pass, $db);
$this->dbName = $db;
if (!$this->link) throw new Exception(mysqli_connect_error());
}
// 寫入操作:使用 UTF-8
public function useUtf8() {
mysqli_select_db($this->link, $this->dbName);
mysqli_query($this->link, "SET NAMES utf8");
mysqli_query($this->link, "SET CHARACTER SET utf8");
mysqli_query($this->link, "SET COLLATION_CONNECTION = 'utf8_general_ci'");
}
// 讀取操作:使用 GBK
public function useGbk() {
mysqli_select_db($this->link, $this->dbName);
mysqli_query($this->link, "SET NAMES gbk");
mysqli_query($this->link, "SET CHARACTER SET gbk");
mysqli_query($this->link, "SET COLLATION_CONNECTION = 'gbk_chinese_ci'");
}
public function query($sql) {
return mysqli_query($this->link, $sql);
}
// ... 其他封裝方法
}
$db = new MySQLiWrapper('localhost', 'user', 'pass', 'db');
// 寫入
$db->useUtf8();
$db->query("INSERT INTO article(title, content) VALUES('測試', '內容')");
// 讀取
$db->useGbk();
$res = $db->query("SELECT * FROM article WHERE id=1");
$row = mysqli_fetch_assoc($res);
// $row['title'] 現為 GBK 編碼,直接輸出至 GBK 頁面無亂碼
SHOW CHARACTER SET 含 utf8、gbk、utf8mb4。$utf8 = mb_convert_encoding($input, 'UTF-8', 'GBK,GB2312,BIG5');| 特性 | mb_convert_encoding | iconv |
|---|---|---|
| 支援字符集 | 最全 | 略少 |
| 自動偵測來源編碼 | 支援(列表優先序) | 不支援,需指定 |
| 執行效率 | 較慢 | 較快 |
| 範例 | mb_convert_encoding($str, 'UTF-8', 'GBK,GB2312,BIG5') | iconv('GBK', 'UTF-8', $str) |
建議:已知來源編碼用 iconv;不確定來源用 mb_convert_encoding 並指定優先序。
utf8mb4,前端暫維持 GBK 輸出(本文方案)。<meta charset="utf-8">,同步移除 PHP 讀取層 GBK 切換。
3. 完成後移除所有 GBK 相關設定,統一 UTF-8 全鏈路。