html_entity_decode() 是 htmlentities() 的逆操作:**將 HTML 實體 (如 `<`, `"`, `〹`) 還原為原始字符**。本文詳解參數、編碼處理、常見陷阱、配套函數對比。
html_entity_decode(string $string, int $flags = ENT_COMPAT | ENT_HTML401, string $encoding = ini_get("default_charset")): string
| 參數 | 類型 | 說明 |
|---|---|---|
$string | string | 包含 HTML 實體的字符串 |
$flags | int | 引號處理方式 + 文檔類型 (見下表) |
$encoding | string | 字符編碼,**強烈建議顯式指定 'UTF-8'** |
| 常量 | 值 | 行為 |
|---|---|---|
ENT_COMPAT | 默認 | 僅轉換雙引號 ",單引號 ' 保持 |
ENT_QUOTES | 轉換雙引號和單引號 (推薦) | |
ENT_NOQUOTES | 不轉換任何引號 | |
ENT_HTML401 | 默認 | HTML 4.01 標準實體 |
ENT_XML1 | XML 實體集 | |
ENT_HTML5 | HTML5 實體集 (含更多命名實體) |
組合用法:ENT_QUOTES | ENT_HTML5
ISO-8859-1, ISO-8859-15, UTF-8, cp866, cp1251, cp1252, KOI8-R, GB2312, BIG5, BIG5-HKSCS, Shift_JIS, EUC-JP, MacRoman, ...
最佳實踐:始終顯式傳遞 `'UTF-8'`**,避免 `default_charset` 配置不一致導致亂碼。
<?php
// 原始字符串
$original = '--> "E.V-Get.com" <--';
// 1. htmlentities() 編碼 (實體化)
$encoded = htmlentities($original, ENT_QUOTES, 'UTF-8');
// $encoded = '--> "E.V-Get.com" <--'
// 2. html_entity_decode() 解碼 (還原)
// 完整還原
$decoded = html_entity_decode($encoded, ENT_QUOTES, 'UTF-8');
// $decoded = '--> "E.V-Get.com" <--'
// 僅解碼雙引號 (默認 ENT_COMPAT)
$decodedNoQuotes = html_entity_decode($encoded, ENT_NOQUOTES, 'UTF-8');
// $decodedNoQuotes = '--> "E.V-Get.com" <--' (單引號實體保留)
// 數字實體解碼 (十進制/十六進制)
$numeric = 'A B'; // A B
echo html_entity_decode($numeric, ENT_QUOTES, 'UTF-8'); // "A B"
?>
| 函數 | 作用 | 轉換範圍 | 典型用途 |
|---|---|---|---|
htmlentities() | 字符 → 實體 | 所有非 ASCII + 特殊字符 | 輸出到 HTML 頁面防 XSS |
html_entity_decode() | 實體 → 字符 | 所有 HTML 實體 (命名/數字) | 讀取已實體化的內容、數據清洗 |
htmlspecialchars() | 字符 → 實體 | 僅 & < > " ' | 表單輸出、屬性值、最常用防 XSS |
htmlspecialchars_decode() | 實體 → 字符 | 僅 & < > " ' | 反轉 htmlspecialchars() |
htmlspecialchars_decode() | 實體 → 字符 | 同上 | 同上 |
| 問題 | 原因 | 解決 |
|---|---|---|
| 解碼後出現 亂碼 | 編碼參數錯誤/不匹配 | 顯式指定 'UTF-8',確保源數據確實是 UTF-8 |
雙重編碼 (如 <) | 重複調用 htmlentities() | 使用 htmlspecialchars($str, ENT_QUOTES, 'UTF-8', false) 第4參數 false 禁止雙重編碼 |
命名實體不解碼 (如 ©) | 編碼標準不匹配 | 使用 ENT_HTML5 旗標,支持更多 HTML5 命名實體 |
| 性能問題 | 大字符串頻繁調用 | 緩存結果、或用 strtr 針對少量固定實體替換 |
<?php
// 1. 存儲前:不處理,存原始用戶輸入 (或標準化編碼)
// 2. 輸出到 HTML 內容區:
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// 3. 輸出到 HTML 屬性值:
echo '';
// 4. 輸出到 JavaScript 變量:
echo '';
// 5. 輸出到 URL 參數:
echo '搜索';
// 6. 若數據庫存的是已實體化字符串 (歷史數據),輸出前解碼再編碼:
$safe = htmlspecialchars(html_entity_decode($storedHtml, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8');
html_entity_decode() 是「實體 → 字符」的標準解碼器,**關鍵在於顯式指定 `ENT_QUOTES | ENT_HTML5` 和 `'UTF-8'`**。配套 htmlspecialchars() (編碼) 形成「存原始、輸出編碼」的防 XSS 最佳實踐。避免雙重編碼、編碼不匹配、命名實體不支持等常見坑。