我很好奇是否有可能使用PDO将值数组绑定到占位符。这里的用例试图传递一个值数组,以便与IN()条件一起使用。

我希望能够这样做:

<?php
$ids=array(1,2,3,7,8,9);
$db = new PDO(...);
$stmt = $db->prepare(
    'SELECT *
     FROM table
     WHERE id IN(:an_array)'
);
$stmt->bindParam('an_array',$ids);
$stmt->execute();
?>

并让PDO绑定并引用数组中的所有值。

目前我正在做:

<?php
$ids = array(1,2,3,7,8,9);
$db = new PDO(...);
foreach($ids as &$val)
    $val=$db->quote($val); //iterate through array and quote
$in = implode(',',$ids); //create comma separated list
$stmt = $db->prepare(
    'SELECT *
     FROM table
     WHERE id IN('.$in.')'
);
$stmt->execute();
?>

这当然是工作,但只是想知道是否有一个内置的解决方案,我错过了?


当前回答

EvilRygy的解决方案对我不起作用。在Postgres中,你可以做另一种解决方法:


$ids = array(1,2,3,7,8,9);
$db = new PDO(...);
$stmt = $db->prepare(
    'SELECT *
     FROM table
     WHERE id = ANY (string_to_array(:an_array, ','))'
);
$stmt->bindParam(':an_array', implode(',', $ids));
$stmt->execute();

其他回答

您首先在查询中设置“?”的个数,然后由一个“for”发送参数 像这样:

require 'dbConnect.php';
$db=new dbConnect();
$array=[];
array_push($array,'value1');
array_push($array,'value2');
$query="SELECT * FROM sites WHERE kind IN (";

foreach ($array as $field){
    $query.="?,";
}
$query=substr($query,0,strlen($query)-1);
$query.=")";
$tbl=$db->connection->prepare($query);
for($i=1;$i<=count($array);$i++)
    $tbl->bindParam($i,$array[$i-1],PDO::PARAM_STR);
$tbl->execute();
$row=$tbl->fetchAll(PDO::FETCH_OBJ);
var_dump($row);

查看PDO:预定义常量,没有PDO::PARAM_ARRAY,你需要在PDOStatement->bindParam上列出

bool PDOStatement::bindParam (mixed $parameter, mixed &$variable [, int $data_type [, int $length [, mixed $driver_options]]])

所以我认为这是不可能实现的。

据我所知,没有任何可能将数组绑定到PDO语句中。

但有两种常见的解决方案:

使用位置占位符(?,?,?,?)或命名占位符(:id1,:id2,:id3) 在美元=内爆(',',array_fill (0, count ($ id), ' ? ')); 之前引用数组 $where = array_map(数组($db, 'quote'), $ids);

这两种选择都是好的和安全的。 我更喜欢第二个,因为它更短,如果我需要它,我可以var_dump参数。 使用占位符,您必须绑定值,最终您的SQL代码将是相同的。

$sql = "SELECT * FROM table WHERE id IN ($whereIn)";

最后一个对我来说很重要的是避免错误“绑定变量的数量与标记的数量不匹配”

它是使用位置占位符的一个很好的例子,只是因为它对传入参数有内部控制。

为了让答案更接近最初使用占位符绑定参数的问题,我做了一些进一步的处理。

这个答案必须在查询中使用的数组中进行两次循环。但它确实解决了为更有选择性的查询使用其他列占位符的问题。

//builds placeholders to insert in IN()
foreach($array as $key=>$value) {
    $in_query = $in_query . ' :val_' . $key . ', ';
}

//gets rid of trailing comma and space
$in_query = substr($in_query, 0, -2);

$stmt = $db->prepare(
    "SELECT *
     WHERE id IN($in_query)";

//pind params for your placeholders.
foreach ($array as $key=>$value) {
    $stmt->bindParam(":val_" . $key, $array[$key])
}

$stmt->execute();

您必须构造查询字符串。

<?php
$ids     = array(1, 2, 3, 7, 8, 9);
$inQuery = implode(',', array_fill(0, count($ids), '?'));

$db = new PDO(...);
$stmt = $db->prepare(
    'SELECT *
     FROM table
     WHERE id IN(' . $inQuery . ')'
);

// bindvalue is 1-indexed, so $k+1
foreach ($ids as $k => $id)
    $stmt->bindValue(($k+1), $id);

$stmt->execute();
?>

chris(评论)和一些人都有麻烦了,建议foreach-loop…

(...)
// bindvalue is 1-indexed, so $k+1
foreach ($ids as $k => $id)
    $stmt->bindValue(($k+1), $id);

$stmt->execute();

... 可能是多余的,因此foreach循环和$stmt->执行可以被替换为…

<?php 
  (...)
  $stmt->execute($ids);