在 PHP 早期版本中,magic_quotes_gpc 會自動對 GET/POST/COOKIE 數據進行轉義(添加反斜槓)。許多開發者嘗試在腳本中用 ini_set('magic_quotes_gpc', 'Off') 關閉它,卻發現無效。本文解釋原因並提供修正方案。
magic_quotes_gpc 在請求解析階段(PHP 腳本執行前)就已生效。當腳本開始運行時,超全局變量($_GET、$_POST、$_COOKIE)已經被轉義過了。此時修改配置只能影響後續請求,無法修正當前請求的數據。
PHP 官方 Bug 追蹤 #32867 明確說明:
magic_quotes_gpc is applied while parsing the request before your PHP script gets control so while you can change this setting in your script, it won't have any effect.
在腳本入口(如公共配置文件)中,檢測配置是否開啟,若開啟則遞歸處理超全局數組:
if (ini_get('magic_quotes_gpc')) {
function stripslashesRecursive(array $array): array {
foreach ($array as $key => $value) {
if (is_string($value)) {
$array[$key] = stripslashes($value);
} elseif (is_array($value)) {
$array[$key] = stripslashesRecursive($value);
}
}
return $array;
}
$_GET = stripslashesRecursive($_GET);
$_POST = stripslashesRecursive($_POST);
$_COOKIE = stripslashesRecursive($_COOKIE);
$_REQUEST = stripslashesRecursive($_REQUEST); // 視情況處理
}
php.ini,務必在所有入口文件最前面引入上述清洗代碼。// 簡單判斷:提交包含引號的表單,觀察 $_POST 中是否出現反斜槓
var_dump($_POST['test']); // 輸入: O'Reilly → 若輸出 O\'Reilly 則受影響
徹底解決仍建議升級 PHP 版本或在 php.ini 中永久關閉:magic_quotes_gpc = Off。