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

PHP get_magic_quotes_gpc 與 addslashes 防 SQL 注入實務指南

     編輯:PHP 相關知識

get_magic_quotes_gpc() 是 PHP 早期提供的防注入機制,用於檢查 magic_quotes_gpc 設定是否開啟。然而此功能自 PHP 5.4 起已移除,現代開發應改用 Prepared Statements (預處理語句)。本文說明歷史機制運作方式,並示範正確的現代防禦寫法。

歷史機制運作方式

回傳值狀態行為
1 (true)開啟PHP 自動對 $_GET、$_POST、$_COOKIE 資料加上反斜線跳脫(如 ' 變 \')。
0 (false)關閉不自動跳脫,開發者需自行處理。

舊式相容寫法(僅供維護舊專案參考)

<?php
$str = $_POST['str'] ?? '';

// 若 magic_quotes_gpc 關閉,手動跳脫
if (!get_magic_quotes_gpc()) {
    $str = addslashes($str);
}

// 現在 $str 可相對安全用於 SQL 拼接(但仍不建議)
$sql = "SELECT * FROM users WHERE name = '$str'";
?>

缺點: addslashes() 僅處理單引號、雙引號、反斜線、NULL 字元,無法完整防禦所有注入向量(如編碼繞過),且容易造成重複跳脫。

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

使用 PDO (PHP Data Objects) 搭配參數綁定,徹底分離 SQL 邏輯與資料,是目前公認最安全、標準的做法。

<?php
try {
    $pdo = new PDO("mysql:host=localhost;dbname=testdb;charset=utf8mb4", "user", "pass", [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_EMULATE_PREPARES => false, // 使用真正的預處理
    ]);

    $stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name AND status = :status");
    $stmt->execute([
        'name' => $_POST['name'] ?? '',
        'status' => 1,
    ]);

    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    // 處理結果...
} catch (PDOException $e) {
    error_log("Database error: " . $e->getMessage());
    // 顯示友善錯誤訊息給使用者
}
?>

關鍵優勢

  • 完全防注入:參數不會被解析為 SQL 指令的一部分。
  • 效能更好:重複執行相同 SQL 時,資料庫只需解析優化一次。
  • 支援多種資料庫:PDO 介面統一,易於遷移。
  • 無需手動跳脫:告別 addslashes、mysql_real_escape_string 等易誤用函式。

遷移建議

  1. 檢查 php.ini 確認 magic_quotes_gpc = Off(PHP 5.4+ 預設即關閉且移除)。
  2. 全專案替換舊式 mysql_* 函式為 PDO 或 MySQLi 準備語句。
  3. 建立資料庫存取層,統一錯誤處理與日誌記錄。
  4. 針對舊資料若含歷史跳脫字元,可撰寫腳本清洗(stripslashes)。
結論: 忘記 get_magic_quotes_gpc 與 addslashes,全面採用 PDO Prepared Statements 才是專業 PHP 開發者的標準配備。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved