P粉6198961452023-09-03 10:06:17
首先,考慮使用命名參數而不是<代码>? 代码>。在這種情況下,您不需要替換任何內容:命名參數清晰且相當容易在日誌中顯示,並且大多數 dbms 用戶端都支援用於偵錯目的。
如果命名參數不可行(由於目前程式碼庫較大或任何其他原因),您有兩種主要方法:
如果您選擇後一種方式,這裡是如何快速且骯髒地完成它的範例:
分多個步驟進行替換:
?
替換為其他極不可能出現在參數或查詢中的內容來準備參數。例如\?
。 ?
,但不會符合第一步中的替換。如果以 \?
替換,則為 (?
\?
替換為 ?
。 注意:此替換的結果不應永遠用作程式中的查詢。這種替代有可能實現以下任何或所有功能:
?
而不是作為參數(例如在註釋中),結果不準確,\?
),結果將不準確。 <?php $query = 'UPDATE `list` set `item`=?,`type`=? WHERE (`id` = ?);'; $params = array( 'item' => '1', 'type' => 'Are you o\'k?', 'id' => 2 ); function substitute_params($query, $params) { $prep_params = str_replace(array("'","?"),array("''","\?"),$params); $query = array_reduce($prep_params, function ($interm, $param) { return preg_replace('/(?<!\\)\?/m', is_numeric($param) ? $param : '\'' . $param . '\'', $interm, 1); }, $query); return "-- Not to be used as a query to database. For demonstration purposes only!\n" .str_replace("\?", "?", $query); } echo substitute_params($query, $params); ?>
輸出:
-- Not to be used as a query to database. For demonstration purposes only! UPDATE `list` set `item`=1,`type`='Are you o''k?' WHERE (`id` = 2);
編輯:要嘗試降低常數字串和帶引號的名稱內問號的影響,您可以嘗試使用此替換:
return preg_replace('/^([^"\'`]*?(?:(?:`[^`]*?`[^"\'`]*?)*?(?:"[^"]*?"[^"\'`]*?)*?(?:\'[^\']*?\'[^\'"`]*?)*?)*?)(?<!\\)\?/m', ''.(is_numeric($param) ? $param : '\'' . $param . '\''), $interm, 1);
它只會取代用 "`'
引用的區塊之外的 ?
。
可以在此處查看示範。
請記住,這不是完全成熟的解析器。例如,它不知道評論。因此錯誤替換的可能性仍然很高。