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

ThinkPHP 資料入庫雙重轉義問題解決方案

     編輯:PHP 綜合知識

問題現象

開啟 magic_quotes_gpc = On 時,ThinkPHP 入庫資料出現雙重反斜線(如 \\'、\\"),導致顯示異常、查詢失敗。

根本原因

  1. PHP magic_quotes_gpc 自動對 $_GET/POST/COOKIE 加斜線。
  2. 2. ThinkPHP 資料庫驅動 escape_string() 再次加斜線,造成雙重轉義。 3. 若資料來源非 GPC(如讀取檔案、API 回應),又缺乏首次轉義,導致漏轉義。

方案一:入口檔案統一處理(推薦)

在 index.php 最頂端加入:

<?php
if (!get_magic_quotes_gpc()) {
    function addslashesDeep($val) {
        return is_array($val) ? array_map('addslashesDeep', $val) : addslashes($val);
    }
    $_POST   = array_map('addslashesDeep', $_POST);
    $_GET    = array_map('addslashesDeep', $_GET);
    $_COOKIE = array_map('addslashesDeep', $_COOKIE);
    $_REQUEST = array_map('addslashesDeep', $_REQUEST);
}
?>

效果:模擬 magic_quotes_gpc = On 行為,確保所有 GPC 資料「恰好」被轉義一次,後續框架 escape_string() 再轉義即為正確的雙重防護(資料庫層)。

方案二:修改資料庫驅動 escape_string()(不推薦)

<?php
// ThinkPHP DbMysql.class.php
public function escape_string($str) {
    // 先移除可能已存在的斜線,再統一加上
    $str = stripslashes($str);
    if ($this->_linkID) {
        return mysql_real_escape_string($str, $this->_linkID);
    }
    return mysql_escape_string($str);
}

缺點:若資料已經過轉義(如方案一處理後),此處 stripslashes 會把正常的轉義移除,導致資料庫層轉義不足;且 mysql_* 函數已棄用。

方案三:遷移至 PDO + Prepared Statement(根治)

ThinkPHP 3.2+ / 5.0+ / 6.0+ 預設使用 PDO,完全不需要手動轉義**:

<?php
// ThinkPHP 6.0 範例
Db::table('users')->insert([
    'name'   => $request->post('name'), // 直接傳入,框架內部用參數綁定
    'email'  => $request->post('email'),
    'bio'    => $request->post('bio'),
]);
// 內部實際執行:INSERT INTO users (name,email,bio) VALUES (?,?,?)
// 參數分開傳送,零 SQL Injection 風險,零轉義煩惱
?>

版本對應建議

ThinkPHP 版本資料庫層建議做法
2.x / 3.0mysql_* + escape_string套用方案一(入口統一處理),並規劃升級
3.1 / 3.2mysqli / PDO 可選強制啟用 PDO,棄用 escape_string
5.0 / 5.1 / 6.0 / 8.0PDO 預設直接使用模型/查詢構建器,零轉義煩惱

驗證測試

<?php
// 測試腳本
$_POST['test'] = "O'Reilly"; // 含單引號
// 套用方案一後
var_dump($_POST['test']); // O\'Reilly (已轉義一次)

// 入庫
Db::table('test')->insert(['content' => $_POST['test']]);
// 資料庫實際儲存:O'Reilly (正確)
// 讀出顯示:O'Reilly (正確)
?>

總結

雙重轉義本質是「責任不清」:PHP 層、框架層、資料庫層各自為政。**現代最佳實務:入口層統一模擬 GPC 轉義(或關閉 magic_quotes),資料庫層全面改用 PDO 參數綁定**,徹底消除轉義邏輯與 SQL Injection 風險。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved