首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 查詢 MSSQL 中文亂碼終極解決方案

     編輯:PHP 綜合知識

問題核心

MSSQL 預設使用 GBK/CP936(中文版 Windows)或 Latin1 儲存中文,而現代 Web 應用採用 UTF-8。編碼鏈路任一環節不一致即產生亂碼:

資料庫儲存編碼 → 驅動傳輸編碼 → PHP 內部編碼 → HTTP 輸出編碼 → 瀏覽器渲染編碼

方案一:驅動層指定字元集 (sqlsrv / PDO_SQLSRV 推薦)

<?php
$dsn = "sqlsrv:Server=192.168.1.100;Database=mydb;CharacterSet=UTF-8";
$pdo = new PDO($dsn, 'sa', 'password', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
// 驅動自動將 GBK/CP936 轉為 UTF-8,PHP 端直接拿正確字串
$stmt = $pdo->query("SELECT name FROM users");
while ($row = $stmt->fetch()) {
    echo $row['name']; // 正常顯示中文
}
?>

關鍵:DSN 加上 CharacterSet=UTF-8,驅動層處理轉碼,最乾淨。

方案二:舊 mssql 擴展調整 php.ini

; php.ini
mssql.charset = "UTF-8"       ; PHP 5.3+ 支援
; 或舊版
mssql.charset = "GBK"         ; 強制驅動以 GBK 讀取,PHP 再自行 iconv

重啟 php-fpm/Apache。缺點:PHP 7.0 移除 mssql 擴展,非長久之計。

方案三:PHP 程式碼層面轉碼 (iconv / mb_convert_encoding)

<?php
// 假設資料庫實際編碼為 GBK
$row = mssql_fetch_assoc($result);
$name = iconv('GBK', 'UTF-8//IGNORE', $row['name']);
// 或
$name = mb_convert_encoding($row['name'], 'UTF-8', 'GBK');

適用:無法更換驅動、無法改 php.ini 的舊專案維護期。

方案四:ADOdb / COM 連線指定代碼頁

<?php
$conn = new COM("ADODB.Connection", NULL, CP_UTF8); // CP_UTF8 = 65001
$conn->Open("Driver={SQL Server};Server=192.168.1.100;Database=mydb;UID=sa;PWD=pass;");
$rs = $conn->Execute("SELECT name FROM users");
while (!$rs->EOF) {
    echo $rs->Fields['name']->Value; // 已為 UTF-8
    $rs->MoveNext();
}
$rs->Close();
$conn->Close();
?>

方案五:資料庫欄位層面統一編碼 (根治)

將舊 varchar/text 改為 nvarchar/ntext (Unicode UCS-2),配合驅動 CharacterSet=UTF-8,徹底消除編碼轉換問題:

ALTER TABLE users ALTER COLUMN name NVARCHAR(100);

優點:儲存層即為 Unicode,支援多國語言,避免 GBK/Big5 衝突。

完整檢查清單 (由資料庫到瀏覽器)

層級檢查項目正確設定
資料庫欄位型別優先 NVARCHAR/NTEXT
資料庫排序規則Chinese_PRC_CI_AS 或 Chinese_PRC_CS_AS
驅動DSN 字元集CharacterSet=UTF-8 (sqlsrv/PDO_SQLSRV)
PHP內部編碼mb_internal_encoding('UTF-8');
PHP輸出標頭header('Content-Type: text/html; charset=UTF-8');
HTMLMeta 標籤<meta charset="UTF-8">
檔案原始碼編碼編輯器儲存為 UTF-8 無 BOM

常見誤區

  • 誤區:以為 SET NAMES UTF8 對 MSSQL 有效。事實:這是 MySQL 指令,MSSQL 無此語法。
  • 誤區:在 SQL 查詢中用 CONVERT(VARCHAR(MAX), col) 解決亂碼。事實:這只是型別轉換,若排序規則不支援中文,轉換後仍會丟字。
  • 誤區:儲存時用 iconv('UTF-8','GBK',$str) 寫入。事實:雙向轉碼極易造成資料損壞,應在驅動層統一處理。

遷移建議路徑

  1. 短期:安裝 sqlsrv/PDO_SQLSRV,DSN 加 CharacterSet=UTF-8。
  2. 中期:核心資料表欄位改 NVARCHAR,清洗現有資料。
  3. 長期:棄用 mssql、COM、ODBC 等舊技術,全面標準化於 PDO_SQLSRV。

總結

MSSQL 中文亂碼本質是「編碼鏈路斷裂」。現代解法:**驅動層統一轉碼 (CharacterSet=UTF-8) + 資料庫層採用 Unicode (NVARCHAR) + 全鏈路 UTF-8**。一次設定,永久解決,拒絕在業務代碼中散落 iconv。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved