PHP PDO 語句是否可以接受表名或列名作為參數?
P粉702946921
P粉702946921 2023-10-17 12:46:05
0
2
647

為什麼我無法將表名傳遞給準備好的 PDO 語句?

$stmt = $dbh->prepare('SELECT * FROM :table WHERE 1');
if ($stmt->execute(array(':table' => 'users'))) {
    var_dump($stmt->fetchAll());
}

還有其他安全的方法可以將表名插入 SQL 查詢嗎?對於安全,我的意思是我不想做

$sql = "SELECT * FROM $table WHERE 1"


#
P粉702946921
P粉702946921

全部回覆(2)
P粉138711794

要了解為什麼綁定表(或列)名稱不起作用,您必須了解準備好的語句中的佔位符如何工作:它們不是簡單地替換為(適當轉義的)字串,並執行產生的SQL。相反,要求「準備」語句的 DBMS 會針對如何執行該查詢提出完整的查詢計劃,包括將使用哪些表和索引,無論您如何填寫佔位符,這些計劃和索引都是相同的。

SELECT name FROM my_table WHERE id = :value 的計劃將與您替換:value 的內容相同,但表面上相似的SELECT name FROM :table WHERE id = :value 無法規劃,因為DBMS 不知道您實際上要從中選擇哪個表。

這也不是像PDO 這樣的抽象程式庫可以或應該解決的問題,因為它會破壞準備好的語句的2 個關鍵目的:1)允許資料庫提前決定如何執行查詢,以及多次使用同一個計劃; 2) 透過將查詢邏輯與變數輸入分開來防止安全性問題。

P粉978742405

表名和列名不能用 PDO 中的參數取代。

在這種情況下,您只需手動過濾和清理資料。實現此目的的一種方法是將簡寫參數傳遞給將動態執行查詢的函數,然後使用 switch() 語句建立用於表名稱的有效值白名單或列名。這樣,使用者輸入就不會直接進入查詢。例如:

function buildQuery( $get_var ) 
{
    switch($get_var)
    {
        case 1:
            $tbl = 'users';
            break;
    }

    $sql = "SELECT * FROM $tbl";
}

透過不保留預設情況或使用傳回錯誤訊息的預設情況,您可以確保只使用您想要使用的值。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板