背景:magic_quotes_gpc 自 PHP 5.4.0 起已移除。本文針對舊版 PHP(≤5.3)維護專案,分析其對序列化資料的影響及相容性處理。
購物車資料序列化存入 Cookie,反序列化時失敗:
<?php
// 寫入 Cookie
$cart = [['goods_id' => 13, 'number' => 1]];
setcookie('cart', serialize($cart));
// 讀取並反序列化
$cart = unserialize($_COOKIE['cart']); // ⚠️ 可能失敗
?>
當 magic_quotes_gpc = On 時,PHP 自動對 GET/POST/COOKIE 資料的單引號、雙引號、反斜線、NULL 字元加上反斜線跳脫。
序列化字串包含大量引號:
a:1:{i:0;a:2:{s:8:"goods_id";i:13;s:6:"number";i:1;}}
經跳脫後變為:
a:1:{i:0;a:2:{s:8:\"goods_id\";i:13;s:6:\"number\";i:1;}}
unserialize() 无法解析被跳脫的字串,導致回傳 false 或拋出錯誤。
<?php
$cart = unserialize(stripslashes($_COOKIE['cart']));
?>
<?php
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);
$_REQUEST = stripslashes_deep($_REQUEST);
}
?>
<?php
$data = ['key' => '值'];
$json = json_encode($data); // 正常
setcookie('test', $json);
// magic_quotes_gpc=On 時,$_COOKIE['test'] 會被加上反斜線
var_dump(json_decode($_COOKIE['test'], true)); // ❌ null
// 解決
var_dump(json_decode(stripslashes($_COOKIE['test']), true)); // ✅ 正常
?>
| 情境 | 處理原則 |
|---|---|
| magic_quotes_gpc = On | 讀取 GPC 資料前統一 stripslashes |
| magic_quotes_gpc = Off | 寫入資料庫/快取前自行 addslashes(或用 Prepared Statement),讀出後 stripslashes |
| 現代 PHP(≥5.4) | 完全忽略,專注於 Prepared Statement 與 json_encode/decode |
get_magic_quotes_gpc() 判斷邏輯json_encode,避免 serialize 類別依賴與編碼問題openssl_encrypt)並簽名驗證希望本文協助您解決舊專案的 magic_quotes_gpc 相容性問題。