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

PHP 連接 MSSQL 中文亂碼完美解決:編碼統一四步法

     編輯:PHP 相關知識

PHP 連接 Microsoft SQL Server (MSSQL) 讀寫中文出現亂碼(問號、方塊、亂碼字符),核心原因是**編碼鏈路不一致**。本文提供「數據庫/表/列、連接層、PHP 文件、瀏覽器輸出」四層編碼統一檢查表,並給出 sqlsrv/pdo_sqlsrv、FreeTDS/ODBC 兩大驅動的具體配置代碼。

編碼統一四層檢查表

層級檢查項標準值驗證方法
1. 數據庫對象數據庫、表、列 校對規則Chinese_PRC_CI_AS / Latin1_General_CI_AS(支援 Unicode 的列用 NVARCHAR)SELECT name, collation_name FROM sys.columns WHERE object_id = OBJECT_ID('dbo.YourTable')
2. 連接層連接字符串 / DSN 指定字符集CharacterSet = UTF-8 / ClientCharset = UTF-8代碼中顯式設置
3. PHP 文件源文件編碼UTF-8 無 BOM編輯器右下角 / file 命令
4. 瀏覽器輸出HTTP Header / Meta 標籤Content-Type: text/html; charset=utf-8Network 面板檢查 Response Headers

方案一:Microsoft 官方驅動 sqlsrv / pdo_sqlsrv (Windows / Linux 均支援)

安裝

# Windows: 下載 DLL 放入 ext/, php.ini 啟用 extension=php_sqlsrv_81_ts.dll
# Linux (Ubuntu):
curl https://packages.microsoft.com/config/ubuntu/22.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
apt update && ACCEPT_EULA=Y apt install msodbcsql18 mssql-tools18
pecl install sqlsrv pdo_sqlsrv
echo "extension=sqlsrv.so\nextension=pdo_sqlsrv.so" > /etc/php/8.1/mods-available/sqlsrv.ini
phpenmod sqlsrv

連接代碼(關鍵:CharacterSet = UTF-8)

<?php
// sqlsrv 過程式風格
$serverName = "127.0.0.1,1433";
$connectionInfo = [
    "UID" => "sa",
    "PWD" => "YourStrongPass123",
    "Database" => "MyDB",
    "CharacterSet" => "UTF-8", // ★ 關鍵:告訴驅動以 UTF-8 傳輸
    "ReturnDatesAsStrings" => true,
];
$conn = sqlsrv_connect($serverName, $connectionInfo);
if (!$conn) die(print_r(sqlsrv_errors(), true));

// 查詢
$sql = "SELECT N'中文測試' AS col1, col2 FROM dbo.TestTable";
$stmt = sqlsrv_query($conn, $sql);
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
    echo $row['col1'] . "\n"; // 正確輸出中文
}
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
?>

PDO 風格(推薦)

<?php
$dsn = "sqlsrv:Server=127.0.0.1,1433;Database=MyDB;CharacterSet=UTF-8";
$pdo = new PDO($dsn, "sa", "YourStrongPass123", [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false, // 使用真實預處理
]);

$stmt = $pdo->query("SELECT N'中文' AS txt");
echo $stmt->fetchColumn(); // 正確輸出
?>

方案二:FreeTDS + ODBC (傳統 Linux 方案,漸被官方驅動取代)

freetds.conf 關鍵配置

# /etc/freetds/freetds.conf
[global]
    tds version = 8.0          # TDS 8.0 支援 Unicode
    client charset = UTF-8     # ★ 關鍵:客戶端字符集
    text size = 64512

[mssql_server]
    host = 192.168.1.100
    port = 1433
    tds version = 8.0
    client charset = UTF-8

ODBC DSN 配置 (/etc/odbc.ini)

[MSSQL]
Driver = FreeTDS
Description = MSSQL via FreeTDS
Server = mssql_server
Database = MyDB
TDS_Version = 8.0
ClientCharset = UTF-8

PHP 連接

<?php
$conn = odbc_connect("MSSQL", "sa", "password");
if (!$conn) die(odbc_errormsg());

// 查詢前設置編碼(某些版本需要)
odbc_exec($conn, "SET NAMES 'utf8'"); // 不一定生效,視驅動而定

$result = odbc_exec($conn, "SELECT col FROM dbo.Table");
while (odbc_fetch_row($result)) {
    echo odbc_result($result, "col") . "\n";
}
odbc_close($conn);
?>

常見坑位與解決

現象原因解決
讀出中文是 ??? 或 連接層未指定 UTF-8,驅動按默認 Latin1 傳輸連接信息加 CharacterSet=UTF-8 / ClientCharset=UTF-8
寫入中文變亂碼列類型為 VARCHAR 非 NVARCHAR,無法存儲 Unicode改用 NVARCHAR(n),或確保數據庫校對規則支援該字符集
PHP 文件編碼非 UTF-8編輯器保存為 GBK/ANSI另存為 UTF-8 無 BOM
瀏覽器顯示亂碼HTTP Header 缺少 charsetheader('Content-Type: text/html; charset=utf-8')
sqlsrv 驅動加載失敗DLL 版本不匹配(TS/NTS、x86/x64、PHP 版本)下載對應版本:php_sqlsrv_81_ts_x64.dll 等

最佳實踐總結

  1. 數據庫列**統一使用 NVARCHAR** 存儲多語言文本。
  2. 連接字符串**顯式指定 CharacterSet=UTF-8 / ClientCharset=UTF-8**。
  3. PHP 源文件**UTF-8 無 BOM**,頁面輸出 **header charset=utf-8**。
  4. 優先使用 **Microsoft 官方 sqlsrv/pdo_sqlsrv 驅動**,免去 FreeTDS/ODBC 多層轉碼麻煩。
  5. 使用 **PDO + 預處理語句**,統一錯誤處理、參數綁定、跨驅動可移植。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved