正確設定 HTTP 回應編碼是避免網頁亂碼、確保多語言內容正常顯示的基礎。PHP 提供兩種主要方式宣告字元編碼,分別作用於 HTTP 標頭與 HTML 文件結構,開發者應依專案架構選擇適當方式,或兩者並用以雙重保障。
使用 header() 函數在輸出任何內容前發送 Content-Type 標頭,瀏覽器會以此為最高優先度解析編碼:
<?php
// 必須在任何 echo、print、HTML 空白之前呼叫
header('Content-Type: text/html; charset=utf-8');
// 後續輸出內容
echo '中文測試內容';
?>
優點:HTTP 標頭優先級最高,不受 HTML meta 標籤干擾;適用於純 PHP 輸出、API 回傳、檔案下載等非 HTML 場景。
注意:若已有輸出(含 BOM、空白行),會觸發 Headers already sent 錯誤。
在 HTML <head> 區塊加入 meta 標籤,供瀏覽器在無 HTTP 標頭或標頭缺失 charset 時參考:
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="utf-8">
<title>頁面標題</title>
</head>
<body>...</body>
</html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<?php
// 在控制器或視圖中
echo '<meta charset="utf-8">';
// 或
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
?>
在 MVC 架構(如 Laravel、CodeIgniter、ThinkPHP)中,建議在基底控制器或入口檔案統一設定:
<?php
// BaseController.php 或 bootstrap/app.php
class BaseController {
public function __construct() {
// 1. HTTP 標頭(最高優先級)
header('Content-Type: text/html; charset=utf-8');
// 2. 視圖共用變數,供版面模板輸出 meta 標籤
$this->view->charset = 'utf-8';
}
}
// layout/main.php 版面模板
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="<?php echo $charset; ?>">
...
</head>
| 錯誤現象 | 可能原因 | 解決方案 |
|---|---|---|
| 中文顯示亂碼( 或 縮) | 資料庫連線編碼、PHP 檔案編碼、HTTP 標頭三者不一致 | 統一全鏈路 UTF-8:資料庫 SET NAMES utf8mb4、PHP 檔案存為 UTF-8 無 BOM、HTTP 標頭宣告 charset |
| header() 無效 | 檔案開頭有 BOM、空白行、或已有 echo 輸出 | 移除 BOM、確保 <?php 為檔案最開頭、輸出前完成所有 header 呼叫 |
| API 回傳 JSON 亂碼 | 未設定 JSON 專用標頭 | 使用 header('Content-Type: application/json; charset=utf-8') 並配合 json_encode($data, JSON_UNESCAPED_UNICODE) |