網頁亂碼是 PHP 開發入門必遇坑點。本文系統歸納四大核心成因:HTML 編碼宣告、PHP 輸出編碼、原始碼檔案編碼、資料庫連線編碼,提供標準化解決方案與驗證清單。
瀏覽器預設編碼可能非 UTF-8,導致中文顯示亂碼。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- 必須放在 head 開頭,越早越好 -->
</head>
PHP 預設輸出編碼可能不一致,需在任何輸出前發送 Header。
<?php
// 必須在第一行、任何 echo/HTML 之前
header('Content-Type: text/html; charset=UTF-8');
// API 回應
header('Content-Type: application/json; charset=UTF-8');
?>
或在 `php.ini` 設定:`default_charset = "UTF-8"`(PHP 5.6+ 預設值)。
編輯器儲存編碼(Big5/GBK)與宣告的 UTF-8 不符。
⚠️ 禁止使用「UTF-8 with BOM」,會輸出隱形字元干擾 Header/JSON/XML。
MySQL 預設 `latin1`,中文存入變問號/亂碼。
-- 建庫建表指定 utf8mb4(支援 Emoji、生僻字) CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE TABLE users (...) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 修改既有 ALTER DATABASE mydb CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
<?php
// PDO(推薦)
$pdo = new PDO('mysql:host=localhost;dbname=mydb;charset=utf8mb4', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
]);
// mysqli
$mysqli = new mysqli('localhost', 'user', 'pass', 'mydb');
$mysqli->set_charset('utf8mb4');
// 查詢前執行(舊版相容)
$pdo->exec("SET NAMES utf8mb4");
$mysqli->query("SET NAMES utf8mb4");
?>
SHOW VARIABLES LIKE 'character_set%'; -- 關鍵項應為 utf8mb4: -- character_set_client, connection, database, results, server
| 層級 | 檢查項目 | 正確值 |
|---|---|---|
| HTML | <meta charset="UTF-8"> | UTF-8 |
| PHP | header('Content-Type: ... charset=UTF-8') | UTF-8 |
| 檔案 | 編輯器儲存編碼 | UTF-8 無 BOM |
| 資料庫 | 資料庫/資料表/連線字符集 | utf8mb4 |
| PHP 設定 | default_charset | UTF-8 |
MySQL `utf8` = `utf8mb3`,僅支援 3 位元組字元,**不支援 Emoji、部分生僻字**。`utf8mb4` 完整支援 4 位元組 Unicode,為現代標準。