我正在尝试编写一个辅助查询函数以将结果集返回给调用者,但是当调用者使用命名参数提供准备好的语句时,我不确定如何将它们绑定在函数中。
function queryDB(string $query, array $param=null) {
global $dbh; //reference the db handle declared in init.php
if (isset($param)) { //query params provided, so a prepared statement
$stmt = $dbh->prepare($query);
for($i = 1; $i <= count($param);$i++) { //bind the parameters 1-by-1
$stmt->bindParam($i, $param[$i]); //
}
$stmt->execute();
} else { //a straight sql query, not a prepared statement
$stmt = $dbh->query($query);
}
$result = $stmt->fetchAll();
return $result;
}
如果我使用未命名参数准备好的语句(例如
queryDB($query, [$name, $age])
和 $query = INSERT INTO users (name, age) VALUES(?, ?)
)调用 $name = "trump"; $age = 18
,则该代码应该可以工作。
但有时我(或其他人)可能会使用命名参数准备好的语句进行调用,例如
$query = INSERT INTO users (name, age) VALUES(:name, :age)
和 $name = "trump"; $age = 18
。现有的 bindParam(i, $value) 不应该工作,但是函数将不知道那些 :name, :age, :whatever
命名参数。我应该如何编写 bindParam(param, value)
来容纳命名和未命名的准备好的语句?假设参数即使在命名时也会以匹配的顺序提供。
绝对没有理由使用
bindParam
。
如果您的 SQL 有命名占位符,那么您的数组必须是关联的。你需要这样称呼它:
queryDB($query, ['name' => $name, 'age' => $age]);
然后您可以使用
foreach($params as $key => $value)
循环并使用 bindParam
但正如我所说,绝对没有理由使用它。
相反,将数组传递给
execute
。
function queryDB(PDO $dbh, string $query, ?array $param = null)
{
$stmt = $dbh->prepare($query);
$stmt->execute($param);
return $stmt->fetchAll();
}
附注您甚至可以删除
if
语句和对 query
的调用。此方法与 prepare
和 execute
执行相同的操作。没有理由在您的代码中出现这样的特殊情况。