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

PHP 統一獲取輸入變量並自動轉義實現

     編輯:PHP 相關知識

早期 PHP 開發常見模式:封裝函數統一處理 $_GET、$_POST、_COOKIE,自動檢測 magic_quotes_gpc 並按需 addslashes() 轉義。本文解析此模式原理與現代替代方案。

歷史代碼解析

<?php
function my_addslashes($string, $force = 0) {
    !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
    if (!MAGIC_QUOTES_GPC || $force) {
        if (is_array($string)) {
            foreach ($string as $key => $val) {
                $string[$key] = my_addslashes($val, $force);
            }
        } else {
            $string = addslashes($string);
        }
    }
    return $string;
}

foreach (array('_COOKIE', '_POST', '_GET') as $_request) {
    foreach ($$_request as $_key => $_value) {
        $_key{0} != '_' && $$_key = my_addslashes($_value); // 變量變量注入符號表
    }
}

echo $urls; // 直接使用 $urls 而非 $_GET['urls']
?>

關鍵技術點

  1. get_magic_quotes_gpc():檢測舊版 PHP 自動轉義開關(PHP 5.4+ 已移除,始終返回 false)
  2. addslashes():為單引號、雙引號、反斜杠、Null 字符加反斜杠
  3. $$_key 變量變量:將 $_GET['urls'] 注入為 $urls 全局變量(**極不推薦**,污染符號表)
  4. $_key{0} != '_':跳過以下劃線開頭的鍵(如 _token)

為什麼現代開發棄用此模式

問題說明
安全幻覺addslashes() 不防 SQL 注入(多字節繞過),不防 XSS(需 htmlspecialchars())
上下文缺失SQL/HTML/JS/Shell 不同上下文需不同轉義,統一處理必漏洞
符號表污染變量變量注入導致變量來源不明、覆蓋風險、IDE 無法分析
魔術引用移除PHP 5.4+ 移除 magic_quotes_gpc,代碼邏輯失效
超全局數組優勢$_GET/$_POST 來源明確、可過濾驗證、框架原生支持

現代最佳實踐

  1. 輸入過濾驗證:用 filter_input()、filter_var()、框架驗證器
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
  1. 輸出上下文轉義:

// HTML
echo htmlspecialchars($str, ENT_QUOTES, 'UTF-8');

// SQL(預處理,無需手動轉義)
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);

// JavaScript
echo json_encode($str);
  1. 統一請求對象:框架提供 Request 類封裝 $_GET/$_POST/$_FILES/$_COOKIE/$_SERVER
// Laravel
$request->input('name');
$request->get('page'); // 僅查詢字符串
$request->post('token'); // 僅 POST 體

// 原生封裝示例
class Request {
    public static function get($key, $default = null) {
        return $_GET[$key] ?? $default;
    }
    public static function post($key, $default = null) {
        return $_POST[$key] ?? $default;
    }
}

歷史代碼反映了早期 PHP「讓開發簡單」的初衷,但現代安全標準要求**輸入驗證、輸出轉義、上下文感知**三位一體,拒絕「一鍵轉義」幻覺。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved