首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 處理輸入轉義字符的最佳實踐:從 Magic Quotes 到現代方案

     編輯:PHP 綜合知識

前言:為什麼需要處理轉義字符?

在 PHP 開發中,處理用戶輸入的特殊字符(如單引號、雙引號、反斜線)是資安的基礎課題。早期 PHP 透過 magic_quotes_gpc 自動轉義 $_GET、$_POST、$_COOKIE 資料,但這機制已於 PHP 5.4 移除。現代開發需採用更精確、可控的策略。

認識 magic_quotes_gpc 歷史包袱

get_magic_quotes_gpc() 回傳 php.ini 中 magic_quotes_gpc 設定值:

  • On (1):自動對單引號 '、雙引號 "、反斜線 \、NULL 字符加上反斜線
  • Off (0):不自動處理,需開發者自行呼叫 addslashes()

關鍵誤區:addslashes() 只適合準備資料給預期已轉義的核心 API,**絕不可**直接用於 SQL 查詢防注入(應改用 Prepared Statements)。

WordPress 3.6 引入的 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;
}

此函數展示了**遞迴處理多維陣列**與**區分純量/陣列**的良好模式。

相容 PHP 5.4+ 的通用輸入過濾方案

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 );
            }
        }
    }
}

說明:

  1. 先判斷 get_magic_quotes_gpc 是否存在或為 Off
  2. 遍歷三大超全域變數
  3. 保護內部變數不被誤處理

三大 Magic Quotes 設定完整對照表

設定項影響範圍可否運行時修改預設值
magic_quotes_gpcHTTP 請求資料 (GET/POST/COOKIE)否On
magic_quotes_runtime外部來源回傳資料 (DB、檔案等)是Off
magic_quotes_sybase以單引號雙寫 '' 取代反斜線轉義單引號,會覆蓋 gpc否Off

實戰案例:資料庫寫入與讀出的轉義處理流程

情境:表單提交包含 HTML 標籤

<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 執行,不寫入資料庫

現代開發建議

  1. 棄用 Magic Quotes:在 php.ini 關閉,避免不可預期行為
  2. 採用 Prepared Statements (PDO/MySQLi):徹底解決 SQL 注入,無需手動轉義
  3. 輸出端視情境編碼:HTML 用 htmlspecialchars(),JS 用 json_encode(),URL 用 urlencode()
  4. 輸入驗證 ≠ 轉義:嚴格驗證格式、長度、型別,轉義只作為最後防線
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved