首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 以 UTF-8 儲存、GBK 輸出的字符集轉換實戰:PHP 連線層動態切換方案

     編輯:MySQL 資料庫相關知識

業務背景

舊系統採用 GBK/Big5,欲逐步遷移至 UTF-8,但前端頁面暫時仍需 GBK 輸出。MySQL 4.1+ 支援連線層字符集設定,可實現「儲存 UTF-8、讀取 GBK」無縫過渡。

資料庫層:建表指定 UTF-8

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。

PHP 連線層:動態切換字符集

封裝兩個方法,分別用於「寫入/更新」與「讀取/查詢」:

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 頁面無亂碼

必要條件與注意事項

  1. MySQL 編譯支援:確認 SHOW CHARACTER SET 含 utf8、gbk、utf8mb4。
  2. 入庫資料必須為合法 UTF-8:前端若非 UTF-8(如 AJAX 預設 UTF-8、表單提交 GBK),需在 PHP 端轉碼:
    $utf8 = mb_convert_encoding($input, 'UTF-8', 'GBK,GB2312,BIG5');
  3. 讀寫分離場景:主庫寫入用 UTF-8,從庫讀取可統一設定 GBK,避免主從字符集不一致導致複寫錯誤。
  4. 避免混用:同一連線內切換字符集需謹慎,建議「一連線一用途」或使用連線池標記。

PHP 轉碼函數比較(補充)

特性mb_convert_encodingiconv
支援字符集最全略少
自動偵測來源編碼支援(列表優先序)不支援,需指定
執行效率較慢較快
範例mb_convert_encoding($str, 'UTF-8', 'GBK,GB2312,BIG5')iconv('GBK', 'UTF-8', $str)

建議:已知來源編碼用 iconv;不確定來源用 mb_convert_encoding 並指定優先序。

遷移路線圖建議

  1. 資料庫層全面改 utf8mb4,前端暫維持 GBK 輸出(本文方案)。
  2. 2. 前端頁面逐步改 <meta charset="utf-8">,同步移除 PHP 讀取層 GBK 切換。 3. 完成後移除所有 GBK 相關設定,統一 UTF-8 全鏈路。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved