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

PHP 表單特殊字元處理全攻略:htmlspecialchars、addslashes、資料庫轉義與最佳實踐

     編輯:PHP 相關知識

前言

表單提交資料包含特殊字元(`<`, `>`, `'`, `"`, `&`, `\` 等)時,若未正確處理,會導致 XSS 攻擊、SQL 注入、資料儲存異常或顯示錯誤。本文系統整理 PHP 核心處理函式、適用場景、常見誤區與防禦策略。

一、核心函式對照表

函式主要用途轉義字元是否可逆典型場景
htmlspecialchars()HTML 輸出編碼(防 XSS)`&` `"` `'` `<` `>`不可逆(顯示用)輸出到 HTML 內容、屬性、JS 字串
htmlentities()所有 HTML 實體編碼所有可轉實體字元不可逆需完整實體化(較少用)
addslashes()字串加反斜線(舊式 SQL/通用)`'` `"` `\` NULstripslashes() 可逆歷史相容、非資料庫字串儲存
stripslashes()移除反斜線對應 `addslashes`可逆處理 `magic_quotes_gpc` 遺留資料
strip_tags()移除 HTML/PHP 標籤標籤結構不可逆(資料遺失)允許部分標籤的內容過濾
mysqli_real_escape_string() / PDO::quote()資料庫專用轉義(防 SQL 注入)依資料庫字元集(含 `\0`, `\n`, `\r`, `\`, `'`, `"`)不可逆(查詢用)**舊式字串拼接 SQL 必用**
PDO Prepared Statements參數綁定(根治 SQL 注入)無需手動轉義N/A**現代最佳實踐**

二、關鍵原則:輸出時轉義,而非輸入時

錯誤做法:儲存前 `htmlspecialchars()` → 資料庫存 `<script>` → 後續 JSON API、CSV 匯出、搜尋皆受汙染。
正確做法:
1. **輸入驗證**:檢查長度、格式、型別、業務規則。
2. **原始儲存**:資料庫存原始用戶輸入(配合 Prepared Statements)。
3. **輸出編碼**:根據輸出語境(HTML、JS、CSS、URL、Shell)套用對應編碼函式。

三、語境感知輸出編碼

輸出語境編碼函式/方法範例
HTML 內容htmlspecialchars($str, ENT_QUOTES, 'UTF-8')`
`
HTML 屬性值同上(雙引號屬性必用 ENT_QUOTES)``
JavaScript 字串json_encode($str)(含引號)``
URL 參數值urlencode($str) / rawurlencode()``
CSS 值無標準函式,嚴格白名單或 `json_encode``style="color: ;"`
Shell 命令參數escapeshellarg() / escapeshellcmd()`exec('convert ' . escapeshellarg($input))`

四、資料庫互動:棄用手動轉義,改用 Prepared Statements

❌ 危險:字串拼接 + 手動轉義

<?php
// 極易漏掉、字元集不符導致繞過
$sql = "SELECT * FROM users WHERE name = '" . mysqli_real_escape_string($link, $_GET['name']) . "'";

✅ 安全:PDO Prepared Statements

<?php
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute([':name' => $_GET['name']]);
$user = $stmt->fetch();

優點:
- 驅動層自動處理轉義與型別
- 查詢計畫可重用(效能)
- 程式碼可讀性高、免維護轉義邏輯

五、常見遺留問題:`magic_quotes_gpc`

PHP 5.4 已移除。若舊專案遷移發現資料多重反斜線(`\\\'`),需在入口點統一清理:

<?php
if (get_magic_quotes_gpc()) {
    function stripslashes_deep($value) {
        return is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
    }
    $_GET = stripslashes_deep($_GET);
    $_POST = stripslashes_deep($_POST);
    $_COOKIE = stripslashes_deep($_COOKIE);
    $_REQUEST = stripslashes_deep($_REQUEST);
}

六、實用封裝建議

<?php
// 通用 HTML 輸出助手
function h(string $str, int $flags = ENT_QUOTES | ENT_SUBSTITUTE, string $encoding = 'UTF-8'): string {
    return htmlspecialchars($str, $flags, $encoding);
}

// 原始輸出(明確標示信任內容)
function raw(string $str): string { return $str; }

// 在模板中使用
//           // 安全
//       // 僅限確信安全內容

七、總結檢查清單

  • [ ] 所有輸出到 HTML 的變數皆經 `htmlspecialchars()`(或模板引擎自動轉義)。
  • [ ] 所有 SQL 查詢使用 Prepared Statements,零手動拼接。
  • [ ] JavaScript 內嵌變數用 `json_encode()`。
  • [ ] URL 參數用 `urlencode()`/`rawurlencode()`。
  • [ ] Shell 參數用 `escapeshellarg()`。
  • [ ] 無 `addslashes()`/`stripslashes()` 用於資料庫操作。
  • [ ] 已清理 `magic_quotes_gpc` 遺留影響。
  • [ ] 內容安全政策 (CSP) 標頭已部署作為纵深防禦。

結語

特殊字元處理的核心在於「語境感知」與「輸出時編碼」。建立統一的輸出助手函式、強制使用 Prepared Statements、移除手動轉義邏輯,即能從根本上杜絕 XSS 與 SQL 注入風險。

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