萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP get_magic_quotes_gpc 檢測與相容處理:避免雙重跳脫的正確姿勢

背景知識

magic_quotes_gpc 是 PHP 早期(< 5.4)自動對 $_GET/$_POST/$_COOKIE 進行 addslashes() 的功能。已於 PHP 5.4.0 移除,但舊專案遷移或共享主機可能仍啟用,需檢測並正確處理避免雙重跳脫。

檢測與處理模式

<?php
/**
 * 統一處理輸入字串:視 magic_quotes 狀態決定是否 addslashes
 *
 * @param string $value 輸入值
 * @param string $type  用途:'text' (SQL字串), 'int' (整數), 'search' (LIKE查詢)
 * @return string 可直接用於 SQL 的字串
 */
function sqlString(string $value, string $type = 'text'): string {
    // 1. 修正 magic_quotes 雙重跳脫
    if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
        $value = stripslashes($value);
    }
    
    // 2. 依用途處理
    switch ($type) {
        case 'text':
            // 單引號跳脫,包裹單引號
            return $value !== '' ? "'" . addslashes($value) . "'" : 'NULL';
            
        case 'search':
            // LIKE 查詢:跳脫 % _ \ 並包裹 %...%
            $escaped = addcslashes($value, '%_\\');
            return "'%" . $escaped . "%'";
            
        case 'int':
            // 強制整數
            return $value !== '' ? (string)intval($value) : '0';
            
        default:
            return "'" . addslashes($value) . "'";
    }
}
?>

現代最佳實踐:完全捨棄 magic_quotes,改用參數化查詢

不應依賴 magic_quotes 或手動 addslashes,應使用 PDO/MySQLi 預處理語句:

<?php
// PDO 參數化查詢(推薦)
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ? AND status = ?");
$stmt->execute([$email, 1]);
$user = $stmt->fetch();

// 批次插入
$stmt = $pdo->prepare("INSERT INTO logs (message, level, created_at) VALUES (?, ?, ?)");
foreach ($logs as $log) {
    $stmt->execute([$log['message'], $log['level'], time()]);
}
?>

遷移檢查清單

  1. php.ini 確認 magic_quotes_gpc = Off、magic_quotes_runtime = Off、magic_quotes_sybase = Off。
  2. 程式碼中移除所有 get_magic_quotes_gpc() 檢查與 stripslashes() 呼叫。
  3. 全面改用預處理語句,禁止字串拼接 SQL。
  4. 輸出 HTML 時使用 htmlspecialchars() 防 XSS(與 SQL 跳脫無關)。
  5. 檢查第三方舊套件是否仍依賴 magic_quotes 行為。

舊專案快速相容包裝器

<?php
// 僅供舊專案過渡期使用,新專案勿採用
class LegacyInput {
    public static function get(string $key, mixed $default = null): mixed {
        $value = $_GET[$key] ?? $default;
        return self::fixMagicQuotes($value);
    }
    
    public static function post(string $key, mixed $default = null): mixed {
        $value = $_POST[$key] ?? $default;
        return self::fixMagicQuotes($value);
    }
    
    private static function fixMagicQuotes(mixed $value): mixed {
        if (is_string($value) && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
            return stripslashes($value);
        }
        if (is_array($value)) {
            return array_map([self::class, 'fixMagicQuotes'], $value);
        }
        return $value;
    }
}
?>

總結

  • magic_quotes_gpc 是已移除的歷史遺物,現代 PHP (5.4+) 不存在。
  • 檢測邏輯僅為舊專案遷移過渡期使用。
  • 參數化查詢是防禦 SQL Injection 的唯一正解,勿再手動跳脫。
  • 輸入處理:過濾/驗證(Filter/Validator)→ 業務邏輯 → 參數化查詢 → 輸出編碼(htmlspecialchars)。
copyright © 萬盛學電腦網 all rights reserved