簡體   English   中英

通過多個PHP變量傳遞SQL WHERE子句

[英]Passing SQL WHERE clause with multiple PHP variables

我有一個AJAX函數,每x輪詢數據庫中的新內容, fetchPosts()調用fetchPosts() (PHP)。

該函數按預期運行,而沒有傳遞任何參數(在這種情況下,它將返回數據庫中的所有行,如下所示),但是當我傳遞給MySQL WHERE子句的變量時,該函數將不起作用。

function fetchPosts($cond = NULL, $oper = NULL, $val = NULL) {
    global $PDOhost, $PDOusn, $PDOpwd, $PDOdb;
    $pdo = new PDO("mysql:host=$PDOhost;dbname=$PDOdb", $PDOusn, $PDOpwd);

    if (isset($cond, $oper, $val)) {
        $stmt = $pdo->prepare("SELECT * FROM messages WHERE hidden=FALSE AND :cond :oper :val ORDER BY id DESC");
        $stmt->execute(array(
            ':cond' => $cond,
            ':oper' => $oper,
            ':val' => $val
            ));
    } else {
        $stmt = $pdo->prepare("SELECT * FROM messages WHERE hidden=FALSE ORDER BY id DESC");
        $stmt->execute();
    }
    ...
}

我正在從其他函數調用該函數。

function debugOnlyShowNew() {
    $lastuseractivity= $_SESSION['lastuseractivity'];
    fetchPosts('timestamp', '>', $lastuseractivity);
}

_SESSION['lastuseractivity']在多個事件上被(重新)定義為date ("Ymd H:i:s") ,並且從兩個函數正確地回顯。 所有時區都是正確的(PHP和MySQL)。

session_start就位於function.php的頂部,在其中定義了debugOnlyShowNew()fetchPosts()

timestampDATETIME MySQL列

以下查詢工作正常,並按預期返回新內容:

SELECT * FROM messages WHERE hidden=FALSE AND timestamp > '2014-01-28 15:24:00' ORDER BY id DESC

是什么賦予了?

您不能直接執行此操作,因為PDO不允許您綁定諸如運算符或列之類的內容。 您將必須通過將字符串串聯在一起來構建SQL。 如果這樣做,請確保將條件和運算符列入白名單。 我建議您嘗試使用某種方式與您的數據庫進行編程交互,例如RedBean: http : //www.redbeanphp.com/

不過,這是一些可行且仍然安全(盡管不是很容易維護)的示例:

function fetchPosts($cond = NULL, $oper = NULL, $val = NULL) {
    global $PDOhost, $PDOusn, $PDOpwd, $PDOdb;
    $pdo = new PDO("mysql:host=$PDOhost;dbname=$PDOdb", $PDOusn, $PDOpwd);
    // whitelist allowed operators
    $validOperators = Array('<','=','>','<>');
    if (!$oper || !in_array($oper, $validOperators) {
         $oper = null;
    }
    // whitelist allowed columns, conditions, etc.
    $validConditions = Array('col1','col2','col3');
    if (!$cond || !in_array($cond, $validConditions) {
         $cond = null;
    }
    $sql = 'SELECT * FROM messages WHERE hidden=FALSE';
    if (isset($cond, $oper, $val)) {
        $sql .= ' AND '.$cond.' '.$oper.' :val'; 
        $params = Array(':val' => $val);
    } else {
        $params = null;
    }
    $sql .= ' ORDER BY id DESC';
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    // do more stuff with results here...
}

這個:

$stmt = $pdo->prepare("SELECT * FROM messages WHERE hidden=FALSE AND :cond :oper :val ORDER BY id DESC");

不能跑

:cond參數旨在包含針對數據庫中字段的值,而不是查詢的單詞。 當您prepare()您的PDOStatement時,將對查詢進行評估,並且sql將在:cond :oper :val因為這絕對不是有效的sql語法。 理解當您准備一條語句時,不會評估值(這就是為什么它實際上可以防止sql注入的原因)

但您可能會執行以下操作:

$cond = 'field';
$oper = '=';
$stmt = $pdo->prepare("SELECT * FROM messages WHERE hidden=FALSE AND $cond $oper :val ORDER BY id DESC");

這將准備以下語句:

$stmt = $pdo->prepare("SELECT * FROM messages WHERE hidden=FALSE AND field = :val ORDER BY id DESC");
$stmt->execute(array(":val" => $val));

這是有效的,但仍然使您擁有“動態” sql語句的可能性

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM