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

PHP mysql_escape_string 與 addslashes 差異深度解析與防注入最佳實踐

     編輯:PHP 相關知識

函數定位

函數來源用途狀態
mysql_escape_string()mysql 擴展MySQL 字串跳脫PHP 5.5 棄用,7.0 移除
mysql_real_escape_string()mysql 擴展連線感知跳脫(需連線資源)同上已移除
addslashes()核心函數通用單/雙引號、反斜線、NULL 跳脫仍可用,但非資料庫專用
mysqli_real_escape_string()mysqli 擴展MySQL 連線感知跳脫現行推薦(程序式)
PDO::quote()PDO驅動感知跳脫含引號現行推薦(物件導向)

跳脫字元對照

<?php
$str = "O'Reilly\n\"Quote\"\x00\x1a\\";

// mysql_real_escape_string 跳脫:\x00 \n \r \ ' " \x1a
// addslashes 跳脫:' " \ NULL
?>

關鍵差異:magic_quotes_sybase 影響

addslashes() 行為受 magic_quotes_sybase 影響(PHP 5.4 移除):

  • On:單引號轉為 ''(Sybase 風格)
  • Off:單引號轉為 \'

mysql_real_escape_string() 始終轉為 \',不受設定影響。

為何不建議手動跳脫

  1. 字元集風險:多位元組字元集(GBK、BIG5)可能繞過跳脫
  2. 人為疏漏:忘記呼叫、雙重跳脫、錯誤連線資源
  3. 維護困難:散落各處的跳脫呼叫難以稽核

現代最佳實踐:參數化查詢

Mysqli 預處理語句

<?php
$mysqli = new mysqli('localhost', 'user', 'pass', 'db');
$stmt = $mysqli->prepare('SELECT * FROM users WHERE email = ? AND status = ?');
$stmt->bind_param('si', $email, $status); // s=string, i=int
$email = "test@example.com";
$status = 1;
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) { /* ... */ }
$stmt->close();
?>

PDO 參數綁定

<?php
$pdo = new PDO('mysql:host=localhost;dbname=db;charset=utf8mb4', 'user', 'pass');
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email AND status = :status');
$stmt->execute([':email' => $email, ':status' => $status]);
foreach ($stmt as $row) { /* ... */ }
?>

不得不手動跳脫時的防護

<?php
// 僅在極少數動態建構 SQL 片段時使用
function escapeSql($mysqli, string $val): string {
    return $mysqli->real_escape_string($val);
}

// 或 PDO
function escapePdo($pdo, string $val): string {
    return $pdo->quote($val); // 含外層引號
}
?>

總結建議

  • 完全避免 mysql_*、addslashes() 用於 SQL
  • 全專案統一使用 PDO + 預處理語句
  • 字元集設定 charset=utf8mb4,確保完整 Unicode 支援
  • 資料庫帳號遵循最小權限原則
  • 啟用 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 異常模式
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved