我正在尝试使用动态PDO查询(如果变量为true,则将where子句添加到查询中)但是我对整数值有问题,这是我的代码:
$params = array();
$cond = array();
$query = "SELECT value FROM `table`";
if (!empty($firstname)) {
$cond[] = "firstname = :fn";
$params[':fn'] = $firstname;
}
if (!empty($lastname)) {
$cond[] = "lastname = :ln";
$params[':ln'] = $lastname;
}
if (count($cond)) {
$query .= ' WHERE ' . implode(' AND ', $cond);
}
$query .= " LIMIT :min, :max";
$params[':min'] = $min; // INTEGER VALUE
$params[':max'] = $max; // INTEGER VALUE
$stmt = $db->prepare($query);
$stmt->execute($params);
问题是PDOStatement::execute
将所有值都视为PDO::PARAM_STR
,LIMIT需要整数值。
我尝试使用PDOStatement::bindValue
使用PDO::PARAM_INT
参数,但我不知道如何在动态查询中使用它。
答案 0 :(得分:2)
您已经在$params
中绑定了一组键和值,因此在准备语句后,循环遍历它并相应地绑定:
$params = array();
$cond = array();
$query = "SELECT value FROM `table`";
if (!empty($firstname)) {
$cond[] = "firstname = :fn";
$params[':fn'] = $firstname;
}
if (!empty($lastname)) {
$cond[] = "lastname = :ln";
$params[':ln'] = $lastname;
}
if (count($cond)) {
$query .= ' WHERE ' . implode(' AND ', $cond);
}
$query .= " LIMIT :min, :max";
$params[':min'] = $min; // INTEGER VALUE
$params[':max'] = $max; // INTEGER VALUE
$stmt = $db->prepare($query);
foreach($params as $key => $value)
{
if(is_int($value))
{
$stmt->bindValue($key, $value, PDO::PARAM_INT);
}
else
{
$stmt->bindValue($key, $value, PDO::PARAM_STR);
}
}
$stmt->execute($params);
请注意,您必须使用bindValue
,因为bindParam
无效。 PHP手册说明了原因:
与PDOStatement :: bindValue()不同,变量被绑定为引用,并且仅在调用PDOStatement :: execute()时进行计算。
一旦foreach
次迭代通过,$value
就不再存在,也无法将用作参考。这正是您必须使用bindValue
答案 1 :(得分:2)
您可以将值与bindParam上的可选第三个参数绑定
像这样:
$stmt->bindParam($key, $value, PDO::PARAM_INT);
如果不起作用,请尝试
$stmt->bindParam($key, intval($value), PDO::PARAM_INT);
这对我来说很好用:
foreach($params as $key => &$value)
$stmt->bindValue($key, $value, get_type($value));
这是我的get_type()函数:
function get_type($value) {
switch(true) {
case is_null($value):
return PDO::PARAM_NULL;
case is_int($value):
return PDO::PARAM_INT;
case is_bool($value):
return PDO::PARAM_BOOL;
default:
return PDO::PARAM_STR;
}
}
我确信有更好的方法可以解决这个问题,但是嘿它有效
(最好使用PDO::bindValue()
而不是PDO::bindParam()
)