亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將數組安全地轉換為 SQL 查詢(PHP7+PDO+SQLite)

將數組安全地轉換為 SQL 查詢(PHP7+PDO+SQLite)

PHP
qq_遁去的一_1 2023-04-28 15:02:54
使用 PHP7+PDO+SQLite,我正在尋找一種方法來使用在前端生成的數組形式的用戶定義過濾器來過濾表中的條目。為清楚起見,這是我正在尋找的示例:例子:數據庫中的表: ID             Firstname      Lastname       Age+--------------+--------------+--------------+-------------+| 0            | John         | Doe          | 21          || 1            | John         | Smith        | 35          || 2            | Alice        | Smith        | 35          || 3            | Bob          | Smith        | 40          |+--------------+--------------+--------------+-------------+過濾器:/*Filters follow the structure:[    "Table Column Name 1" => [Match1 OR Match2 OR ...],    AND    "TCN 2" ...]Any column name not provided should match any value.*/[    "Firstname" => ["John"]]// ^ fetchAll() returns rows with ID 0 and 1[    "Firstname" => ["John", "Alice"],    "Lastname" => ["Smith"]]// ^ ID 1 and 2 (but not 3)我需要找到一個可以將上面的數組轉換為 SQL 查詢的函數,以獲取與過濾器匹配的所有行。出于性能原因,我想使用 SQL(我沒有太多經驗)而不是獲取所有行并使用 PHP 過濾它們來執行此操作。我知道我可以按照以下方式做一些事情:// Untested - for illustration purposes only$filter = [    "Firstname" => ["John", "Alice"],    "Lastname" => ["Smith"]];$sql = "SELECT * FROM table_name WHERE ";foreach ($filter as $column => $matching_values) {    foreach ($matching_values as $match) {        $sql .= $column . " == " . $match . " OR ";    }    // Ugly way of removing trailing ` OR `    $sql = substr($sql, 0, -4);    $sql .= " AND ";}// Ugly way of removing trailing ` AND `$sql = substr($sql, 0, -5);echo $sql;但這引入了一個巨大的 SQL 注入安全漏洞。我想知道是否有一種簡單而有效且安全的方法來實現這一目標。如果需要,也可以更改過濾器的格式,例如更改為 RegEx(如果有人可以用 RegEx 替換上面示例中最里面的數組,則加分)?;蛘撸ɑ蛄硗猓?,一種以可搜索的方式描述我的問題的簡單方法可能會有所幫助,因為我無法對此進行太多研究,因為我無法很好地表達它。
查看完整描述

1 回答

?
尚方寶劍之說

TA貢獻1788條經驗 獲得超4個贊

這將是我已經在我的網站上教授的幾種技術的有趣組合,即

  • 動態創建 WHERE 子句

  • 為 IN 子句創建準備好的語句

  • 白名單以防止SQL 注入

最后會變成這樣

$allowed = ["Firstname", "Lastname"];


$conditions = [];

$parameters = [];

foreach ($filter as $key => $values) {

? ? if (array_search($key, $allowed, true) === false) {?

? ? ? ? throw new InvalidArgumentException("invalid field name!");?

? ? }

? ? $conditions[] = "`$key` in (".str_repeat('?,', count($values) - 1) . '?'.")";

? ? $parameters = array_merge($parameters, $values);

}

$sql = "SELECT * FROM table_name ";

if ($conditions)

{

? ? $sql .= " WHERE ".implode(" AND ", $conditions);

}

將生成您正在尋找的查詢,


SELECT * FROM table_name WHERE WHERE `Firstname` in (?,?) AND `Lastname` in (?)

以及要在 中使用的值數組PDO::execute(),制作防彈解決方案,其中值通過參數保護,文件名通過白名單過濾保護不受保護


我唯一的懷疑是問題中出現的案例可能過于簡單化了。一旦您不僅需要精確匹配,還需要部分匹配或更大/更小的比較,代碼的復雜性就會飆升。


查看完整回答
反對 回復 2023-04-28
  • 1 回答
  • 0 關注
  • 162 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號