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

PHP 字串安全過濾函數完整指南:htmlentities、htmlspecialchars、strip_tags、intval 實戰選型

     編輯:PHP 相關知識

PHP 字串安全過濾函數完整指南:htmlentities、htmlspecialchars、strip_tags、intval 實戰選型

「永遠不要信任用戶輸入」是 Web 安全鐵律。PHP 內建多種過濾函數,各有適用場景與限制。本文系統整理 6 大核心函數:mysql_real_escape_string、addslashes、htmlentities、htmlspecialchars、strip_tags、intval,解析原理、適用場景、常見誤區與現代最佳實踐。

函數快速對比表

函數核心用途防護目標現代建議
mysql_real_escape_stringSQL 字串轉義SQL 注入棄用,改用 PDO 預處理
addslashes通用字串轉義SQL 注入 (不完整)不推薦,字元集敏感、易雙重轉義
htmlentities所有字元轉 HTML 實體XSS適用完整內容編碼,較重
htmlspecialchars特殊字元轉 HTML 實體XSS首選,效能好、覆蓋核心風險字元
strip_tags移除 HTML/JS/PHP 標籤XSS、標籤注入允許特定標籤時使用,不可單獨防 XSS
intval強制轉整數型別混淆、SQL 注入 (數值欄位)數值參數驗證首選

核心函數詳細解析

1. htmlspecialchars() — XSS 防護首選

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

echo $safe; // 瀏覽器顯示原始文字,不執行腳本
?>
  • 轉換字元:& → &、" → " (需 ENT_QUOTES)、' → ' (需 ENT_QUOTES)、< → <、> → >。
  • 三大參數:$string、$flags = ENT_QUOTES | ENT_SUBSTITUTE、$encoding = 'UTF-8'。
  • 最佳實踐:輸出時 呼叫,而非輸入時。儲存原始資料,顯示時轉義。

2. htmlentities() — 完整編碼

  • 將所有有 HTML 實體對應的字元轉換 (含 accented chars、特殊符號)。
  • 較 htmlspecialchars 重,輸出體積大。
  • 適用:匯出純文字報表、郵件內容、需完整保留視覺字元場景。

3. strip_tags() — 移除標籤 (非完整 XSS 防護)

<?php
$input = '

正常段落

粗體'; echo strip_tags($input); // 正常段落alert(1)粗體 echo strip_tags($input, '

'); // 保留

和 :

正常段落

alert(1)粗體 ?>

關鍵限制:

  • 不處理屬性事件:<img src=x onerror=alert(1)> → 標籤被保留 (若允許 img) 但 onerror 執行。
  • 不處理 CSS expression、JavaScript 協定連結。
  • 結論:strip_tags 只能作為輔助清理,**永遠搭配 htmlspecialchars 輸出編碼**。

4. intval() — 數值參數鐵律

<?php
// 取得 ID 參數
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
// $id 永遠是整數,SQL: "SELECT * FROM posts WHERE id = $id" 安全 (無引號注入風險)

// 同理適用:age, page, limit, offset, status 等數值欄位
$page = max(1, intval($_GET['page'] ?? 1));
$limit = min(100, max(1, intval($_GET['limit'] ?? 20)));
?>
  • 將任意輸入強制轉為整數,非數值字串回傳 0。
  • 適用於已知為整數的參數 (ID、分頁、狀態碼)。
  • 浮點數參數用 floatval(),布林用 filter_var($v, FILTER_VALIDATE_BOOLEAN)。

5. 過時函數:mysql_real_escape_string & addslashes

mysql_real_escape_string:

  • 需資料庫連線、受連線字元集影響、僅防 SQL 注入。
  • PHP 7.0 移除 mysql_* 擴展,PDO/mysqli 皆有更好方案。

addslashes:

  • 盲目加反斜線,不處理字元集、多位元組繞過 (GBK 0xbf27)、% _ 萬用字元。
  • magic_quotes_gpc (PHP 5.4 移除) 曾自動執行此函數,造成雙重轉義災難。

現代輸入處理最佳實踐流程

  1. 輸入驗證:型別、格式、長度、範圍、白名單 (如 filter_var, intval, 正則)。
  2. 資料儲存:原始資料入庫 (使用 PDO 預處理),不做 HTML 編碼。
  3. 輸出編碼:根據輸出上下文選擇編碼:
    • HTML 內容:htmlspecialchars($str, ENT_QUOTES, 'UTF-8')
    • HTML 屬性:同上,確保雙引號編碼
    • JavaScript 變數:json_encode($str) (自動處理引號、換行、Unicode)
    • URL 參數:urlencode() / rawurlencode()
    • SQL (極少數無法預處理):pdo->quote()
  4. 內容安全策略 (CSP):HTTP 標頭 Content-Security-Policy 作為第二道防線。

常見誤區速查

誤區正確做法
儲存前 htmlspecialchars 入庫儲存原始資料,輸出時編碼。入庫編碼會導致資料污染、重複編碼、搜尋失效。
strip_tags 就能防 XSS無法防屬性事件、JS 協定、CSS 攻擊。必須搭配 htmlspecialchars。
addslashes 防 SQL 注入使用 PDO/mysqli 預處理。
過濾關鍵字 (select, union...)誤殺率高、繞過易。參數化查詢才是根本解。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved