開發 PHP 網頁時,<title> 標籤中的中文顯示為亂碼(如「測試頁面」變成「娴佺▼椤甸潰」或「????」)是經典的編碼不匹配問題。瀏覽器在解析 HTML 時,若未明確告知文件編碼,會依據預設編碼(通常為 ISO-8859-1 或系統地區編碼)解碼位元組流,導致 UTF-8 編碼的中文位元組被錯誤解讀。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>中文標題正常顯示</title>
</head>
<body>
...
<meta charset> 必須放在 <head> 區塊的最開頭,且在 <title> 之前。瀏覽器解析到 <title> 時需已知編碼,否則已來不及修正。<meta charset="utf-8">,效果等同且更簡潔。<?php
// 必須在任何輸出(含空白、BOM)之前
header('Content-Type: text/html; charset=utf-8');
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>中文標題</title>
...
解決標題亂碼只是冰山一角,確保全站編碼一致需檢查以下四個層面:
| 層面 | 檢查項目 | 工具/指令 |
|---|---|---|
| PHP 檔案儲存編碼 | 所有 .php 檔案以 UTF-8 無 BOM 儲存 | 編輯器右下角 / file -i filename.php |
| PHP 內部編碼設定 | php.ini 設定 default_charset = "UTF-8"mbstring.internal_encoding = UTF-8 |
php -i | grep charset |
| 資料庫連線編碼 | PDO: charset=utf8mb4mysqli: set_charset('utf8mb4') |
檢查連線程式碼 |
| 資料表/欄位編碼 | 建表指定 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci |
SHOW CREATE TABLE tbl |
| HTTP 回應標頭 | 回應含 Content-Type: text/html; charset=utf-8 |
瀏覽器 DevTools Network 標籤 |
| HTML meta 標籤 | <meta charset="utf-8"> 位於 <head> 首行 |
View Source 檢查 |
header()、session_start()、JSON API 等。務必選「UTF-8 無 BOM」。utf8 僅支援 3 位元組字元,無法儲存 Emoji 或部分生僻字,必須用 utf8mb4。將以下程式碼存為 charset_check.php 訪問,快速排查編碼配置:
<?php
header('Content-Type: text/plain; charset=utf-8');
echo "=== PHP 環境編碼檢查 ===\n";
echo "default_charset: " . ini_get('default_charset') . "\n";
echo "mbstring.internal_encoding: " . ini_get('mbstring.internal_encoding') . "\n";
echo "mbstring.http_output: " . ini_get('mbstring.http_output') . "\n";
echo "\n=== 檔案編碼檢查 (當前檔) ===\n";
$content = file_get_contents(__FILE__);
echo "偵測到 BOM: " . (strncmp($content, "\xEF\xBB\xBF", 3) === 0 ? "是 ❌" : "否 ✅") . "\n";
echo "\n=== 測試中文輸出 ===\n";
echo "標題測試:中文標題正常顯示\n";
PHP 網頁中文亂碼本質是「編碼宣告缺失或不一致」。遵循 檔案儲存 UTF-8 無 BOM → PHP 內部設定 UTF-8 → 資料庫連線 utf8mb4 → HTTP 標頭宣告 UTF-8 → HTML meta charset=utf-8 的完整鏈路,即可從根源杜絕亂碼問題。養成「新專案第一步配置編碼」的習慣,比事後除錯高效百倍。