Php PDO IN()数组语句和占位符
我在SO上找到了这段代码,这对于同时使用PDO和IN()语句非常有用Php PDO IN()数组语句和占位符,php,mysql,pdo,warnings,Php,Mysql,Pdo,Warnings,我在SO上找到了这段代码,这对于同时使用PDO和IN()语句非常有用 $values = explode(',', $values) ; # 1,4,7 $placeholders = rtrim(str_repeat('?, ', count($values)), ', ') ; $query = "SELECT * FROM table WHERE id IN ($placeholders)"; $stm = $db->prepare($query) ; $stm->exec
$values = explode(',', $values) ; # 1,4,7
$placeholders = rtrim(str_repeat('?, ', count($values)), ', ') ;
$query = "SELECT * FROM table WHERE id IN ($placeholders)";
$stm = $db->prepare($query) ;
$stm->execute($values) ;
但是,如何在查询中添加其他内容,使查询如下所示:
$query = "SELECT * FROM table WHERE id IN ($placeholders) AND product=?";
$stm = $db->prepare($query) ;
$stm->execute(array($values,$product)) ; //error happens when adding product placeholder
我原以为这样行得通,但我得到:
警告:PDOStatement::execute()[PDOStatement.execute]:SQLSTATE[HY093]:无效参数编号:绑定变量的数量与第3行($stm行)中的令牌数量不匹配
你知道如何让它按预期运行吗
已更新执行到阵列,仍不工作。您忘记准备了^_^
$query = "SELECT * FROM table WHERE id IN ($placeholders) AND product=?";
$stm = $db->prepare($query) ;
$stm->execute($values,$product) ; //p00f
除此之外execute()
应该只有一个参数
所以上面的根本不起作用强>
这里的问题是execute
需要一个数组。不能传递多个数组,更糟糕的是,不能嵌套数组
我们已经有了一个非常好的$values
数组,所以在创建占位符字符串后,让我们重新使用它
$values = explode(',', $values) ; # 1,4,7
$placeholders = rtrim(str_repeat('?, ', count($values)), ', ') ;
$query = "SELECT * FROM table WHERE id IN ($placeholders) AND product=?";
// New!
$values[] = $product;
$stm = $db->prepare($query);
$stm->execute($values);
解决方案
如果$values
是一个数组,则这应该可以工作:
$query = "SELECT * FROM table WHERE id IN ($placeholders) AND product=?";
$stm->execute(array_merge($values, array($product)));
解释
execute()。通过添加array\u merge($values,array($product))
可以创建一个在末尾添加了$product
的数组,因此查询应该可以正常工作
请参见此处的演示:,其他解决方案可以是(如果您喜欢:param_name=$value方式,如我所示):
我不确定这是否是最好的、最优化的解决方案,但它更容易让人理解:)如果您有一个复杂的大查询,并且希望调试它,它会很有帮助
(我很好奇是否有人有很好的理由为什么不这样做)占位符版本,如果你需要的话
$values = [1, 4, 7, 8];
$placeholders = preg_filter('/^/', ':prefix_', array_keys($values)));
$query = 'SELECT * FROM table WHERE id IN ( '. implode(', ', $placeholders) . ')';
$stmt = $db->prepare($query);
if (count($values) > 0) {
foreach ($values as $key => $current_value) {
$stmt->bindValue($placeholders[$key] , $current_value, PDO::PARAM_STR);
}
}
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
谢谢Neal,不过,我确实准备好了,我只是展示了两次通话之间发生变化的部分。我还将它改为使用:$stm->execute(array($values,$product));我仍然会得到一个错误,我会重新编辑并在上面发布这看起来是迄今为止最有效的答案,与Tadeck的答案相同,但更干净的执行语句只有一个数组。它还应该始终知道产品=?占位符将始终是不在计数中的额外值,对吗?还有一件事,如果是这样的话,如果我们要在查询的末尾添加一个附加项,比如,和type=?,我们是否只说$values[]=$type;在$values[]=$product之后;行,或者我们可以将它们合并成一行?类似于,$values[]=($product,$type);也许吧?@Maverick:我是故意这样做的(在execute()
call中合并数组),因为您以后可以在代码中始终使用$values
。如果在追加$product
后执行此操作,则只需处理一个不需要的额外元素:)但决定权在您,请记住不要使代码复杂化:)如果您想在一行中执行类似$values[]=($product,$type)
的操作,只要这样做:$values=array\u merge($values,array($product,$type))
@Tadeck:Tadeck和Charles的答案都很好。我希望我能接受这两种情况。@bart:使用array\u splice()
意味着您将首先添加一些元素,然后删除它们,以将$values
返回到其原始值。效率不高,更重要的是,可能会降低(并且可能会降低)可维护性。但是array_slice()
是可以考虑的代码>很好。谢谢:)
$params = array(
':product' => $product
);
$_in_params = array();
foreach ( $_in_values as $idx_in => $value_in)
{
$_in_params[] = ':param_in_'.$idx_in;
$params[':param_in_'.$idx_in] = $value_in;
}
$query .= "SELECT * FROM table WHERE id IN (".join(',',$_in_params).") AND product=:product";
$values = [1, 4, 7, 8];
$placeholders = preg_filter('/^/', ':prefix_', array_keys($values)));
$query = 'SELECT * FROM table WHERE id IN ( '. implode(', ', $placeholders) . ')';
$stmt = $db->prepare($query);
if (count($values) > 0) {
foreach ($values as $key => $current_value) {
$stmt->bindValue($placeholders[$key] , $current_value, PDO::PARAM_STR);
}
}
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);