get_magic_quotes_gpc() 是 PHP 早期 (≤ 5.3) 的**魔術引號**功能檢測函數。該功能**已在 PHP 5.4 移除**,**PHP 7+ 完全不存在**。現代專案**絕對不應依賴**此功能,而應使用**預處理語句**防禦 SQL 注入。本文說明歷史背景、遷移策略與現代最佳實踐。
php.ini 可設定 magic_quotes_gpc = On。$_GET, $_POST, $_COOKIE 中的 ', ", \, NULL 字元會**自動加反斜線轉義**。get_magic_quotes_gpc() 回傳 1 (On) 或 0 (Off)。$_FILES, $_SERVER, 資料庫讀出資料等。addslashes())。; php.ini
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
<?php
// 運行時關閉 (若支援)
if (function_exists('set_magic_quotes_runtime')) {
set_magic_quotes_runtime(0);
}
// 若已開啟,需在入口處清理
if (get_magic_quotes_gpc()) {
function stripslashes_deep($value) {
return is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
}
$_GET = stripslashes_deep($_GET);
$_POST = stripslashes_deep($_POST);
$_COOKIE = stripslashes_deep($_COOKIE);
}
?>
<?php
// PDO (推薦)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // 真正預處理
]);
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND status = ?');
$stmt->execute([$email, 1]);
$user = $stmt->fetch();
// 參數自動轉義、型別處理,完全防注入
?>
<?php
// MySQLi
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$mysqli->set_charset('utf8mb4');
$stmt = $mysqli->prepare('SELECT * FROM users WHERE email = ?');
$stmt->bind_param('s', $email); // 's'=string, 'i'=int, 'd'=double, 'b'=blob
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
?>
<?php
function h(string $str): string {
return htmlspecialchars($str, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
echo '' . h($userInput) . '';
?>
| 舊代碼 (危險) | 問題 | 現代修正 |
|---|---|---|
mysql_query("SELECT * FROM users WHERE name='$name'"); | 直接拼接,注入漏洞 | PDO/MySQLi 預處理 |
$name = addslashes($name); mysql_query(...) | addslashes 不完整 (不處理 %, _ 等)、編碼問題 | 預處理 |
if (!get_magic_quotes_gpc()) $name = addslashes($name); | 依賴已移除函數、雙重轉義風險 | 移除判斷,用預處理 |
mysql_real_escape_string($name) | 需連線資源、編碼依賴連線字符集、易忘 | 預處理 (自動處理) |
magic_quotes_gpc = Off** (預設即關閉)get_magic_quotes_gpc()、set_magic_quotes_runtime()、addslashes() 用於 SQL**utf8mb4**htmlspecialchars() 防 XSS**password_hash() 儲存**極少數場景:
$like = '%' . $pdo->quote($keyword) . '%'; (注意 quote() 包含引號)$pdo->quote($value) (PDO) 或 $mysqli->real_escape_string($value) (MySQLi),但**必須設定正確連線字符集**。