Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php PDO IN()数组语句和占位符_Php_Mysql_Pdo_Warnings - Fatal编程技术网

Php 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

我在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->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);