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 (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());
// 顯示友善錯誤訊息給使用者
}
?>
addslashes、mysql_real_escape_string 等易誤用函式。php.ini 確認 magic_quotes_gpc = Off(PHP 5.4+ 預設即關閉且移除)。mysql_* 函式為 PDO 或 MySQLi 準備語句。stripslashes)。結論: 忘記get_magic_quotes_gpc與addslashes,全面採用 PDO Prepared Statements 才是專業 PHP 開發者的標準配備。