[英]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()
。
timestamp
是DATETIME
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.