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

PHP 讀取 MSSQL JSON 資料中文亂碼完整解決方案

     編輯:PHP 綜合知識

問題背景

  • 專案編碼:UTF-8(PHP、HTML、資料庫連線)
  • 資料庫:SQL Server 2008,預設編碼 Chinese_PRC_CI_AS (代碼頁 936 / GBK)
  • 現象:json_encode() 輸出中文顯示為 null 或亂碼

根因分析

  1. json_encode() 僅接受 UTF-8 編碼字串;若輸入含非 UTF-8 字元,會回傳 false (PHP 5.5+) 或將該字元編碼為 \u0000 / null。
  2. SQL Server 回傳資料為 GBK 編碼,PHP 未轉碼直接送入 json_encode。

解決方案:雙向編碼轉換

1. 讀取資料:GBK → UTF-8

header('Content-Type: application/json; charset=utf-8');

$conn = sqlsrv_connect($server, $connOpts);
$sql = "SELECT * FROM products WHERE id = ?";
$stmt = sqlsrv_query($conn, $sql, [$id]);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);

// 關鍵:將每個欄位由 GBK 轉 UTF-8
foreach ($row as $key => $val) {
    if (is_string($val)) {
        $row[$key] = iconv('GBK', 'UTF-8//IGNORE', $val);
    }
}

echo json_encode($row, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

2. 寫入資料:UTF-8 → GBK

$name = $_POST['name']; // UTF-8
$nameGbk = iconv('UTF-8', 'GBK//IGNORE', $name);

$sql = "INSERT INTO products (name) VALUES (?)";
sqlsrv_query($conn, $sql, [$nameGbk]);

完整範例:員工資料增刪改查

<?php
header('Content-Type: application/json; charset=utf-8');
require '../conn.php'; // 返回 $conn (sqlsrv 連線)

$action = $_POST['action'] ?? 'list';

switch ($action) {
    case 'list':
        $stmt = sqlsrv_query($conn, "SELECT seq, employeeID, employeeName, department FROM employees");
        $data = [];
        while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
            foreach ($row as $k => $v) {
                $row[$k] = is_string($v) ? iconv('GBK', 'UTF-8//IGNORE', $v) : $v;
            }
            $data[] = $row;
        }
        echo json_encode(['code' => 0, 'data' => $data], JSON_UNESCAPED_UNICODE);
        break;

    case 'save':
        $seq = $_POST['seq'] ?? 0;
        $id = iconv('UTF-8', 'GBK//IGNORE', $_POST['employeeID']);
        $name = iconv('UTF-8', 'GBK//IGNORE', $_POST['employeeName']);
        $dept = iconv('UTF-8', 'GBK//IGNORE', $_POST['department']);

        if ($seq) {
            $sql = "UPDATE employees SET employeeID=?, employeeName=?, department=?, updateTime=GETDATE() WHERE seq=?";
            $params = [$id, $name, $dept, $seq];
        } else {
            $sql = "INSERT INTO employees (employeeID, employeeName, department, createTime, updateTime) VALUES (?, ?, ?, GETDATE(), GETDATE())";
            $params = [$id, $name, $dept];
        }
        $ok = sqlsrv_query($conn, $sql, $params);
        echo json_encode(['code' => $ok ? 0 : 1, 'msg' => $ok ? 'success' : 'fail']);
        break;
}
?>

進階優化

  • PDO + sqlsrv 驅動:使用 PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8 (驅動 5.8+ 支援),自動處理編碼轉換,無需手動 iconv。
  • 資料庫層面:欄位改用 NVARCHAR 存儲 Unicode,並設定資料庫/欄位 Collation 為 Latin1_General_100_CI_AS_SC,配合 N'字串' 寫入,徹底避免編碼問題。
  • 錯誤處理:iconv 加 //IGNORE 忽略無法轉換字元,或用 //TRANSLIT 近似替換;生產環境建議記錄轉換失敗日誌。

驗證清單

  1. PHP 檔案儲存為 UTF-8 無 BOM。
  2. HTML 頁面 <meta charset="utf-8">。
  3. 資料庫連線字串包含 CharacterSet=UTF-8 (PDO) 或驅動層設定 UTF-8。
  4. 輸出 JSON 前 header('Content-Type: application/json; charset=utf-8')。
  5. 使用 JSON_UNESCAPED_UNICODE 讓中文直接顯示而非 \uXXXX。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved