[PHP] 如何對 MySQL 的 UTF16 進行讀寫

檸檬爸在開發 PHP 網站的時候有運用到 MySQL 資料庫,由於特殊的應用需求,在某些表格的結構中需要用到 utf16_unicode_ci 的編碼。但在利用某些 PHP framework 例如 (CodeIgnitor) 對資料庫進行讀寫的時候由於 character-set 預設為 utf8 所以會出現亂碼的情況,本篇想要介紹遇到此依情況時可能的解決方法。

假設以下是我們的目標表格結構:

其中 test 欄位的編碼是使用 utf16_unicode_ci 原因是因為有一些特殊字元,例如以下我們列出的範例,其中 test 欄位中的內容,並不被 utf8 所支援,如果欄位選擇 utf8_unicode_ci 則會出現?的亂碼!

解決方法:

解決方法的想法是在讀寫的時候,順便轉換資料型態到二進位或是十六進位,以下我們列出在讀寫時候會需要用的 SQL 指令:

SELECT CONVERT(`test` USING Binary) from `t1` WHERE a = 1;

INSERT INTO `t1`(`a`, `b`, `test`) VALUES (9, 2, CONVERT(0xd841df79 USING utf16))

利用 PHP (CodeIgnitor) 將 utf-16 的資料從 MySQL 讀出:

$mysqli = $this->get_mysqli();
$result = $mysqli->query('SELECT CONVERT(test USING binary) as temp FROM `t1` WHERE a = 1 FOR UPDATE;');
$row = mysqli_fetch_assoc($result);
echo mb_convert_encoding($row["temp"], 'UTF-8', 'UTF-16');

利用 PHP (CodeIgnitor) 將 utf-16 的資料寫入 MySQL 裡面:

首先我們需要將已知的字串轉換成 Binary 的形式,例如 “0xd841df79″,備註:這邊由於我們的網站也不支援 utf-16 編碼,所以以下的程式碼則是使用”界刂車立”代替我們要的輸入:

$input = "界刂車立"; echo mb_strtoupper(bin2hex(mb_convert_encoding($input, 'UTF-16BE', 'UTF-8')));

得到輸出結果:

D841DF79D860DEE2

利用產生出來 UTF-16 的十六位元碼,我們利用以下的程式碼輸入表格中: 

$word = "0xD841DF79D860DEE2";
$mysqli = $this->get_mysqli(); 
$query = sprintf('INSERT INTO `t1` (`a`,`b`,`test`) VALUES (11, 8, CONVERT(%s USING utf16))', $word); 
$result = $mysqli->query($query); 
$mysqli->commit();

最後我們的 t1 表格會呈現以下的樣貌: