在 PHP 開發中,處理用戶輸入數據的安全性始終是核心課題。htmlspecialchars、strip_tags 與 addslashes 是三個最基礎且高頻使用的字符串處理函數,它們雖然看似簡單,但各自有著明確的適用場景與潛在陷阱。本文將從原理、差異、最佳實踐三個維度,為你徹底釐清這三大函數的正確用法。
strip_tags(string $string, array|string|null $allowed_tags = null) 旨在從字符串中移除 HTML、XML 以及 PHP 標籤。你可以通過第二個參數指定允許保留的標籤(如 <b>、<i>)。
>),函數可能返回錯誤結果或截斷數據。onclick、style)依然存在,仍可能引發 XSS 攻擊。僅用於完全可信的數據源(如後台編輯器輸出的純文本預覽),嚴禁用於用戶提交數據的安全過濾。現代項目建議改用 HTMLPurifier 等專業庫。
將特殊字符轉換為對應的 HTML 實體,防止瀏覽器將其解析為標籤或腳本。默認轉換四大字符:
| 原字符 | 轉義後 |
|---|---|
| & (和號) | & |
| " (雙引號) | " |
| < (小於號) | < |
| > (大於號) | > |
htmlspecialchars(string $string, int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, ?string $encoding = null): string
<input value='...'>)。'UTF-8'),避免多字節字符截斷導致繞過轉義。所有輸出到 HTML 頁面的動態數據:模板變量、API 返回的 JSON 嵌入頁面、日志輸出等。這是防禦 XSS 的核心手段。
將所有可轉換字符(含多字節字符、特殊符號)轉為實體。雖然徹底,但會導致頁面體積膨脹、可讀性下降,且對 UTF-8 等現代編碼支持不如 htmlspecialchars 完善。一般業務無需使用,僅在特殊編碼兼容場景下考慮。
addslashes() 在單引號(')、雙引號(")、反斜線(\)與 NUL 字符前添加反斜線;stripslashes() 則執行逆操作。
magic_quotes_gpc(PHP 5.4 已移除),會造成數據污染。$stmt->execute([$userInput]),驅動層自動處理轉義,徹底分離代碼與數據。mysqli_real_escape_string()(僅限無法使用預處理的極端場景)。| 場景 | 推薦函數/方案 | 核心原則 |
|---|---|---|
| 輸出到 HTML 內容/屬性 | htmlspecialchars($str, ENT_QUOTES, 'UTF-8') | 上下文感知輸出編碼 |
| 輸出到 JavaScript 變量 | json_encode() + 模板非轉義標記 | 結構化序列化 |
| 寫入數據庫 | PDO 預處理 / 參數綁定 | 代碼數據分離 |
| 清理富文本編輯器內容 | HTMLPurifier / DOMPurify | 白名單標籤/屬性過濾 |
| 簡單去標籤(可信源) | strip_tags($str, '<b><i>') | 僅作展示用途 |
金律:永遠在輸出時根據上下文進行編碼,而非在輸入時「清洗」數據。輸入驗證(長度、格式、類型)與輸出編碼是兩道獨立防線。