首頁  >  問答  >  主體

PHP PDO 語句是否可以接受表名或列名作為參數?

為什麼我無法將表名傳遞給準備好的 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粉702946921P粉702946921342 天前585

全部回覆(2)我來回復

  • P粉138711794

    P粉1387117942023-10-18 11:56:39

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

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

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

    回覆
    0
  • P粉978742405

    P粉9787424052023-10-18 09:40:36

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

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

    function buildQuery( $get_var ) 
    {
        switch($get_var)
        {
            case 1:
                $tbl = 'users';
                break;
        }
    
        $sql = "SELECT * FROM $tbl";
    }

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

    回覆
    0
  • 取消回覆