魔術引號 是 PHP 早期為防 SQL 注入而引入的自動轉義機制,但因副作用大、行為不一致,已於 PHP 5.4 移除。理解其運作差異對維護舊專案、遷移程式碼仍有參考價值。
| 設定項目 | magic_quotes_gpc | magic_quotes_runtime |
|---|---|---|
| 影響範圍 | GET、POST、COOKIE 輸入資料 | 檔案讀取、exec() 結果、SQL 查詢結果 |
| 觸發時機 | 請求開始 (腳本啟動時) | 每次存取執行期產生的資料 |
| 轉義字元 | ' " \ NULL | ' " \ NULL |
| 可在程式中設定 | ❌ 無 set_magic_quotes_gpc() |
✅ set_magic_quotes_runtime(0|1) |
| 檢測函數 | get_magic_quotes_gpc() |
get_magic_quotes_runtime() |
| 預設值 | PHP 5.3 前為 On,後為 Off | 預設 Off |
由於伺服器設定不一,程式碼必須同時相容 On/Off 兩種情況:
<?php
// 統一處理函數:確保資料只被轉義一次
function safeAddslashes($data) {
// 遞迴處理陣列
if (is_array($data)) {
foreach ($data as $key => $value) {
$data[$key] = safeAddslashes($value);
}
return $data;
}
// 字串處理:若 magic_quotes_gpc 開啟則已轉義,否則手動轉義
if (!get_magic_quotes_gpc()) {
return addslashes($data);
}
return $data;
}
// 使用範例
$_POST = safeAddslashes($_POST);
$_GET = safeAddslashes($_GET);
$_COOKIE = safeAddslashes($_COOKIE);
// 處理檔案/資料庫讀取資料 (受 magic_quotes_runtime 影響)
$data = file_get_contents('data.txt');
if (!get_magic_quotes_runtime()) {
$data = addslashes($data);
}
// 寫入 SQL 後,讀出時需移除反斜線
$result = $pdo->query("SELECT * FROM table");
$row = $result->fetch(PDO::FETCH_ASSOC);
$cleanData = stripslashes($row['field']); // 還原原始資料
?>
| 函數 | 功能 | 備註 |
|---|---|---|
addslashes() |
在 ' " \ NULL 前加反斜線 | 手動轉義 |
stripslashes() |
移除反斜線 | 讀取資料庫資料還原用 |
get_magic_quotes_gpc() |
回傳 1=開啟, 0=關閉 | 檢測 GPC 狀態 |
get_magic_quotes_runtime() |
回傳 1=開啟, 0=關閉 | 檢測 Runtime 狀態 |
set_magic_quotes_runtime() |
設定 Runtime 狀態 | 建議在程式啟動時設為 0 |
magic_quotes_gpc = Off、magic_quotes_runtime = Offprepare() + bindParam(),根本不需轉義htmlspecialchars()、JS 用 json_encode()、Shell 用 escapeshellarg()addslashes()/stripslashes()/get_magic_quotes_*() 呼叫magic_quotes、addslashes、stripslashes