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

PHP 頁面亂碼根因分析與三大編碼一致性解決方案

     編輯:PHP 相關知識

前言

PHP 頁面亂碼 90% 來自三個編碼環節不一致:檔案儲存編碼、頁面宣告編碼、資料庫連線編碼。本文系統拆解各環節機制、常見錯誤組合與對應解決方案,並說明 Apache 預設編碼干擾問題。

三大編碼環節詳解

1. 檔案編碼

  • 指 `.php`、`.html` 檔案本身在磁碟上的位元組編碼。
  • 編輯器 (VS Code、PhpStorm、Notepad++) 儲存時決定。
  • 建議:全專案統一 **UTF-8 無 BOM**。BOM 會導致 `header()` 失效、`session_start()` 警告。

2. 頁面宣告編碼

  • 告訴瀏覽器以何種編碼解碼頁面內容。
  • 兩種方式:
    1. HTTP Header (優先級最高):header('Content-Type: text/html; charset=utf-8'); (必須在任何輸出前呼叫)
    2. HTML Meta:<meta charset="utf-8"> (HTML5 簡寫) 或 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  • HTTP Header 若存在,瀏覽器會忽略 Meta。

3. 資料庫連線編碼

  • PHP 與 MySQL 之間傳輸資料的編碼協議。
  • MySQL 內部儲存編碼 (如 `latin1`、`utf8mb4`) 與連線編碼可不同,MySQL 會自動轉換。
  • 關鍵指令:SET NAMES utf8mb4 (等同設定 `character_set_client`、`connection`、`results` 三者)。

常見錯誤組合與解決

場景現象原因解決
資料庫 utf8mb4,頁面宣告 GB2312中文亂碼連線編碼未設定,MySQL 用預設 latin1 傳輸,頁面以 GB2312 解碼 UTF-8 位元組查詢前執行 $pdo->exec("SET NAMES gbk"); 或統一改用 UTF-8
檔案存 UTF-8,頁面宣告 GB2312中文亂碼檔案位元組為 UTF-8,瀏覽器用 GB2312 解碼統一編碼:檔案存 GB2312 (ANSI) 或頁面宣告 UTF-8
虛擬主機 Apache 強制 AddDefaultCharset UTF-8頁面宣告 GB2312 但瀏覽器仍用 UTF-8HTTP Header 優先級 > Meta,Apache 發送 Content-Type: text/html; charset=utf-8.htaccess 加 AddDefaultCharset GB2312 或聯繫管理員修改 vhost 設定
修改檔案後亂碼 (ZendStudio 等)編輯器以錯誤編碼開啟並儲存IDE 不自動偵測編碼,依預設開啟設定 IDE 專案編碼為 UTF-8,或用支援自動偵測編碼的編輯器

MySQL 連線編碼深度解析

<?php
// PDO (推薦)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass');

// MySQLi
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$mysqli->set_charset('utf8mb4'); // 必須在查詢前呼叫

// 手動執行 (所有介面通用)
$pdo->exec("SET NAMES utf8mb4");
// 等同於
$pdo->exec("SET character_set_client = utf8mb4");
$pdo->exec("SET character_set_connection = utf8mb4");
$pdo->exec("SET character_set_results = utf8mb4");

注意:SET NAMES utf8 (無 mb4) 僅支援 3 位元組字元,**無法儲存 Emoji (4 位元組)**,生產環境請用 utf8mb4。

Apache 預設編碼干擾解決

# .htaccess (放於網站根目錄)
AddDefaultCharset GB2312
# 或
AddDefaultCharset UTF-8

# 若無 .htaccess 權限,修改虛擬主機設定
# 
#     AddDefaultCharset UTF-8
# 

原理:Apache `AddDefaultCharset` 發送 HTTP Header,優先級高於頁面 Meta。虛擬主機用戶只能用 `.htaccess` 覆蓋。

最佳實踐檢查清單

  1. ✅ 專案所有檔案 **UTF-8 無 BOM** 儲存 (編輯器設定)。
  2. ✅ 入口檔案最早處呼叫 header('Content-Type: text/html; charset=utf-8');。
  3. ✅ HTML `` 含 `` (雙重保險)。
  4. ✅ 資料庫連線建立後立即執行 SET NAMES utf8mb4。
  5. ✅ 資料庫表/欄位 `CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`。
  6. ✅ 檢查 Apache/Nginx 無衝突 `AddDefaultCharset` / `charset` 設定。
  7. ✅ 表單送資 `
    ` (雙重保險)。

總結

亂碼本質是編碼不一致。建立「全站 UTF-8 無 BOM、資料庫 utf8mb4、連線 SET NAMES utf8mb4、HTTP Header 宣告 UTF-8」四位一體規範,並納入專案規範文件與 Code Review 清單,可徹底根治亂碼問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved