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

PHP 頁面 UTF-8 中文亂碼徹底解決:Header、檔案編碼、BOM、資料庫、附件下載全鏈路指南

     編輯:PHP 綜合知識

UTF-8 亂碼是 PHP 開發最常見坑。本文從 HTTP 響應頭、PHP 檔案編碼、BOM 標記、MySQL 連線、附件下載檔名五個維度,給出完整排查與修復清單。

1. HTTP 響應頭:最優先、最高效

// 放在所有輸出之前(包括空白、HTML)
header('Content-Type: text/html; charset=UTF-8');

等同於 Apache AddDefaultCharset UTF-8 或 php.ini: default_charset = "UTF-8"(PHP 5.6+ 預設)。

2. PHP 檔案編碼:編輯器存檔設定

  • **VS Code**:右下角編碼選 **UTF-8**(非 UTF-8 with BOM)
  • **PhpStorm**:File → File Encoding → UTF-8
  • **Notepad++**:編碼 → 轉為 UTF-8 編碼(無 BOM)
  • **Sublime**:File → Save with Encoding → UTF-8

檢查方法:file -i your.php 輸出 text/x-php; charset=utf-8

3. BOM (Byte Order Mark) 陷阱

UTF-8 BOM = EF BB BF 三字節** 會被 PHP 視為輸出內容,導致:

  • session_start() 失敗:Cannot send session cache limiter - headers already sent
  • header()、setcookie() 失效
  • 頁面頂部出現隱形空白或 

移除方法:

  • 編輯器另存為 **UTF-8 無 BOM**
  • 命令列批次移除:find . -name "*.php" -exec sed -i '1s/^\xEF\xBB\xBF//' {} \;

4. MySQL 連線與資料表編碼

$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
]);
  • 資料庫/資料表/欄位建議 **utf8mb4**(支援 Emoji、生僻字)
  • 避免舊版 utf8(實為 utf8mb3,僅 3 字節)
  • 舊專案 mysql_query("SET NAMES UTF8") 改為 SET NAMES utf8mb4

5. 附件下載:中文檔名編碼處理

$filename = '中文報表.xlsx';
$encoded = rawurlencode($filename); // RFC 5987 標準

header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header("Content-Disposition: attachment; filename*=UTF-8''{$encoded}");
header('Content-Length: ' . filesize($filepath));
readfile($filepath);

舊瀏覽器兼容:

$ua = $_SERVER['HTTP_USER_AGENT'];
if (preg_match('/MSIE|Trident/', $ua)) {
    $filename = iconv('UTF-8', 'GBK', $filename); // IE 老版本
    header("Content-Disposition: attachment; filename=\"$filename\"");
} else {
    header("Content-Disposition: attachment; filename*=UTF-8''{$encoded}");
}

6. 字符串截取:mb_substr 替代 substr

function utf8_substr($str, $len) {
    return mb_substr($str, 0, $len, 'UTF-8');
}
// 或通用函數
function msubstr($str, $start, $len, $charset = 'UTF-8', $suffix = true) {
    $slice = mb_substr($str, $start, $len, $charset);
    return $suffix && mb_strlen($str, $charset) > $len ? $slice . '...' : $slice;
}

完整排查清單(按優先級)

  1. header('Content-Type: text/html; charset=UTF-8') 在最頂部
  2. 所有 PHP/HTML/JS/CSS 檔案存為 **UTF-8 無 BOM**
  3. 資料庫連線 SET NAMES utf8mb4,表欄位 utf8mb4_unicode_ci
  4. 資料庫、表、欄位編碼一致性檢查
  5. 表單頁 <meta charset="UTF-8"> + accept-charset="UTF-8"
  6. 所有 iconv/mb_convert_encoding 來源/目標編碼正確
  7. 下載檔名用 filename*=UTF-8'' 格式
  8. JSON 輸出 json_encode($data, JSON_UNESCAPED_UNICODE)

常見誤區

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
誤區正確做法
以為 meta charset 就夠了HTTP Header 優先級高於 meta,必須雙重保險
用 utf8_encode/decode 處理中文僅適用 ISO-8859-1 ↔ UTF-8,中文需 iconv/mb_convert_encoding
忽略 BOM 導致 session 失效全專案掃描移除 BOM,編輯器設定預設無 BOM