在 PHP 開發中,處理用戶輸入的特殊字符(如單引號、雙引號、反斜線)是資安的基礎課題。早期 PHP 透過 magic_quotes_gpc 自動轉義 $_GET、$_POST、$_COOKIE 資料,但這機制已於 PHP 5.4 移除。現代開發需採用更精確、可控的策略。
magic_quotes_gpc 歷史包袱get_magic_quotes_gpc() 回傳 php.ini 中 magic_quotes_gpc 設定值:
'、雙引號 "、反斜線 \、NULL 字符加上反斜線addslashes()關鍵誤區:addslashes() 只適合準備資料給預期已轉義的核心 API,**絕不可**直接用於 SQL 查詢防注入(應改用 Prepared Statements)。
wp_slash() 參考實作/**
* 為字串或字串陣列加上反斜線
* @since 3.6.0
* @param string|array $value 輸入值
* @return string|array 處理後的值
*/
function wp_slash( $value ) {
if ( is_array( $value ) ) {
foreach ( $value as $k => $v ) {
if ( is_array( $v ) ) {
$value[$k] = wp_slash( $v ); // 遞迴處理多維陣列
} else {
$value[$k] = addslashes( $v );
}
}
} else {
$value = addslashes( $value );
}
return $value;
}
此函數展示了**遞迴處理多維陣列**與**區分純量/陣列**的良好模式。
if ( ! function_exists( 'get_magic_quotes_gpc' ) || ! get_magic_quotes_gpc() ) {
foreach ( array( '_COOKIE', '_POST', '_GET' ) as $superglobal ) {
foreach ( $$superglobal as $key => $val ) {
// 略過以底線開頭的鍵(如 _TOKEN 等內部變數)
if ( $key[0] !== '_' ) {
$$superglobal[$key] = addslashes( $val );
}
}
}
}
說明:
get_magic_quotes_gpc 是否存在或為 Off| 設定項 | 影響範圍 | 可否運行時修改 | 預設值 |
|---|---|---|---|
magic_quotes_gpc | HTTP 請求資料 (GET/POST/COOKIE) | 否 | On |
magic_quotes_runtime | 外部來源回傳資料 (DB、檔案等) | 是 | Off |
magic_quotes_sybase | 以單引號雙寫 '' 取代反斜線轉義單引號,會覆蓋 gpc | 否 | Off |
<img alt="" width="400" height="300" src="/Upfiles/201105/images/1306657040.jpg" />
magic_quotes_gpc(推薦)修改 php.ini:magic_quotes_gpc = Off
// 1. 寫入前移除魔術引號加的斜線 $content = stripslashes( $_POST['content'] ); // 2. 後續統一使用 $content 變數 // 3. 寫入資料庫(搭配 Prepared Statements 最安全) // 4. 讀出時再次移除可能殘留的斜線 $output = stripslashes( $row['content'] );
stripslashes() 專門移除 addslashes() 加入的反斜線,適用於清理資料庫或表單回傳資料。
| 環境 | 輸入處理 | 輸出處理 | 核心邏輯 |
|---|---|---|---|
magic_quotes_gpc = On |
**不要**重複 addslashes() |
若輸入端誤加過,需 stripslashes() |
PHP 已自動轉義,資料庫實際儲存無斜線 |
magic_quotes_gpc = Off |
**必須** addslashes() 或改用 Prepared Statements |
**不需** stripslashes() |
轉義僅協助 SQL 執行,不寫入資料庫 |
php.ini 關閉,避免不可預期行為htmlspecialchars(),JS 用 json_encode(),URL 用 urlencode()