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

PHP 常用轉義函數完整指南:addslashes、htmlspecialchars、htmlentities、mysql_real_escape_string 差異對比

     編輯:PHP 綜合知識

PHP 資料轉義函數全解析:防 SQL 注入、防 XSS、資料安全處理

PHP 提供多種轉義函數,針對不同輸出場景 (SQL、HTML、Shell、JSON) 有專用函數。混用或誤用會導致安全漏洞或資料損壞。本文詳細對比核心函數差異、適用場景與最佳實踐。

核心函數對比表

函數用途轉義字元反轉義適用場景
addslashes()通用字串轉義' " \ NULstripslashes()無專用 DB 驅動時的 SQL (不推薦)
htmlspecialchars()HTML 輸出& " ' < >htmlspecialchars_decode()所有輸出到 HTML 的變數 (防 XSS)
htmlentities()HTML 完整實體化所有可轉實體字元html_entity_decode()需完整實體編碼的 XML/HTML 匯出
mysql_real_escape_string()MySQL 專用 SQL\x00 \n \r \ ' " \x1a自動 (資料庫層)舊版 mysql_* (已移除),改用 PDO/MySQLi
strip_tags()移除 HTML/PHP 標籤移除而非轉義無簡單內容過濾 (不安全,易繞過)

詳細用法與注意事項

1. addslashes() - 歷史遺留,勿用於現代 SQL

$str = "O'Reilly";
echo addslashes($str); // O\'Reilly

// ⚠️ 問題:
// 1. 不支援多位元組字元集 (GBK 等) 導致注入繞過
// 2. PHP 5.3 前 magic_quotes_gpc 自動開啟會導致雙重轉義
// 3. 已被 PDO/MySQLi 參數化查詢取代

2. htmlspecialchars() - 防 XSS 核心

<?php
$input = '';
$safe = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
// 輸出:<script>alert("XSS")</script>

$input2 = "Tom & Jerry";
$safe2 = htmlspecialchars($input2); // 預設 ENT_COMPAT 不轉單引號
// 輸出:Tom & Jerry

// 旗標說明:
// ENT_COMPAT   預設,只轉雙引號
// ENT_QUOTES   轉單雙引號 (推薦)
// ENT_NOQUOTES 不轉引號
// ENT_HTML5    HTML5 模式 (PHP 5.4+)

3. htmlentities() - 完整實體化

$str = '中文 © 2024';
echo htmlentities($str, ENT_QUOTES, 'UTF-8');
// 輸出:中文 © 2024 (中文通常不轉,視 charset 而定)

// 差異:htmlentities 會轉換所有有實體對應的字元
// htmlspecialchars 只轉 & " ' < > 五個字元

4. 現代資料庫轉義:PDO/MySQLi 參數化查詢 (唯一正解)

<?php
// PDO (推薦)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass');
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email AND status = :status');
$stmt->execute([':email' => $email, ':status' => 1]);
$user = $stmt->fetch();

// MySQLi
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$stmt = $mysqli->prepare('SELECT * FROM users WHERE email = ?');
$stmt->bind_param('s', $email);
$stmt->execute();
$result = $stmt->get_result();

// 參數化查詢優勢:
// 1. 徹底分離代碼與資料,免疫 SQL 注入
// 2. 自動處理編碼、轉義、類型轉換
// 3. 可重複執行提升效能
// 4. 程式碼更清晰

5. strip_tags() - 簡單但不安全

$html = '

正常段落

'; echo strip_tags($html); // 輸出:正常段落 alert(1) alert(2) (屬性事件處理器未被移除!) // 允許特定標籤 echo strip_tags($html, '

'); // 保留 p, b, i

場景對應速查表

場景正確處理錯誤示範
輸出到 HTML 內容htmlspecialchars($var, ENT_QUOTES, 'UTF-8')直接 echo $var
輸出到 HTML 屬性值htmlspecialchars($var, ENT_QUOTES, 'UTF-8')無引號包裹屬性值
輸出到 JavaScript 字串json_encode($var) (自動處理引號、換行、Unicode)手動 addslashes
輸出到 URL 參數urlencode($var) / rawurlencode()直接拼接
輸出到 Shell 命令escapeshellarg($var) / escapeshellcmd()直接拼接命令
SQL 查詢PDO/MySQLi 參數化查詢addslashes / 字串拼接
JSON 輸出json_encode($var, JSON_UNESCAPED_UNICODE)手動拼接 JSON

安全建議總結

1. SQL 唯一正解:參數化查詢 (PDO/MySQLi),絕不手動轉義
2. HTML 輸出預設:htmlspecialchars($var, ENT_QUOTES, 'UTF-8')
3. JavaScript 輸出:json_encode() 自動處理所有邊界情況
4. 不要信任 strip_tags() 防 XSS,屬性事件處理器、CSS expression 等可繞過
5. 統一編碼 UTF-8:資料庫、連線、PHP 檔案、HTML meta、HTTP Header 全鏈路 UTF-8
6. 推薦使用 HTML Purifier 處理富文本內容 (允許部分 HTML 標籤的場景)

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