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

PHP addslashes / stripslashes 與 magic_quotes_gpc 交互深度解析:歷史遺留與現代最佳實踐

     編輯:PHP 綜合知識

歷史背景:magic_quotes_gpc

PHP ≤ 5.3 時代,magic_quotes_gpc = On 會自動對 $_GET/POST/COOKIE 進行 addslashes 轉義(單引號→\', 雙引號→\", 反斜槓→\\, NULL→\0)。目的是防止 SQL 注入,但帶來嚴重問題:

  • 雙重轉義:開發者再次 addslashes 導致 \\' 入庫
  • 輸出污染:直接 echo 顯示 \'
  • 非資料庫場景誤傷:JSON、HTML、Shell 參數等不需要 SQL 轉義
  • 可移植性差:代碼在 On/Off 環境行為不同

PHP 5.4 已移除,現代代碼不應依賴此特性。

addslashes / stripslashes 本質

函數作用適用場景
addslashes($str)預定義字符前加反斜槓:\' \" \\ \0構建 SQL 字符串字面量 (不推薦,見下文)
stripslashes($str)移除反斜槓轉義 (成對移除)修正 magic_quotes 污染的數據

交互矩陣 (歷史參考)

magic_quotes_gpc寫入時 addslashes讀出時 stripslashes結果
On否否✅ 正常 (系統已轉義)
On是否❌ 雙重轉義:數據庫存 \\'
On是是✅ 正常 (抵消)
Off否否❌ 注入風險 / 語法錯誤
Off是否✅ 正常
Off是是❌ 過度清洗:合法 \ 被移除

現代最佳實踐:預處理語句

<?php
// ❌ 過時:手動拼接 SQL (即使用 addslashes 也不安全:編碼、二進制、邊界情況)
$sql = "INSERT INTO users (name) VALUES ('" . addslashes($name) . "')";

// ✅ 正確:PDO 預處理 (參數化查詢)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass');
$stmt = $pdo->prepare('INSERT INTO users (name) VALUES (?)');
$stmt->execute([$name]); // 驅動層自動處理轉義、類型、編碼

// ✅ 正確:MySQLi 預處理
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$stmt = $mysqli->prepare('INSERT INTO users (name) VALUES (?)');
$stmt->bind_param('s', $name);
$stmt->execute();

何時仍需 addslashes/stripslashes?

  • 維護老專案:無法重寫為預處理,需兼容 magic_quotes On/Off 環境
  • 非 SQL 場景:構建 Shell 命令 (escapeshellarg 更好)、LDAP 過濾器、正則模式字面量
  • 數據清洗:接收第三方已轉義數據,需 stripslashes 還原

兼容性封裝 (僅限老專案維護)

<?php
/**
 * 寫入前統一處理 (兼容 magic_quotes On/Off)
 */
function cleanInput(string $str): string {
    // 1. 若 magic_quotes 開啟,先還原
    if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
        $str = stripslashes($str);
    }
    // 2. 統一加斜槓 (用於舊式拼接 SQL)
    return addslashes($str);
}

/**
 * 讀出後統一處理
 */
function cleanOutput(string $str): string {
    if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
        return stripslashes($str);
    }
    return $str;
}

// 使用
$name = cleanInput($_POST['name']);
// ... 入庫 ...
$name = cleanOutput($row['name']);
// ... 輸出 ...

常見誤區

  • ❌ str_replace("'", "''", $str) 替代 addslashes — 僅處理單引號,漏掉 \ " \0,且編碼相關漏洞 (GBK 多字節注入)。
  • ❌ 相信 addslashes 能防所有注入 — 不能 (邊界: 多字節編碼、二進制數據、未加引號的數值注入)。
  • ❌ 對已入庫數據再次 addslashes — 導致反斜槓指數增長。
  • ✅ 預處理語句是唯一標準答案 (PHP 5.1+ 普及 PDO/MySQLi)。

總結

  1. magic_quotes_gpc 是歷史錯誤,已被移除,新代碼假設 Off。
  2. addslashes 不是防注入銀彈,僅用於字符串字面量構建。
  3. 所有數據庫交互**必須使用預處理語句** (PDO/MySQLi)。
  4. 輸出到 HTML 用 htmlspecialchars,JS 用 json_encode,Shell 用 escapeshellarg — 按上下文轉義,而非通用加斜槓。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved