解决方案使用PDO将数组放入IN子句中

时间:2014-07-29 09:50:55

标签: php mysql sql pdo

我一直在尝试在 this thread 中提出两个最受欢迎的解决方案,以解决在PDO预处理语句中使数组工作的变通方法。

解决方案1 ​​

$qMarks = str_repeat('?,', count($ids) - 1) . '?';
$sth = $db->prepare("SELECT * FROM myTable WHERE id IN ($qMarks)");
$sth->execute($ids);

解决方案2

$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 . ')'
);

但我收到错误

Invalid parameter number: mixed named and positional parameters

将每个应用于我的代码。该错误是否意味着如果我对$_POST["group"](数组)使用其中一个解决方案,我不能将{BindValue用于$_POST["reply_name"]?有没有解决方案?

原始代码(仅当IN Clause只有一个值时才有效):

  $id_group = $_POST["group"];
  $reply_name = $_POST["reply_name"];

  foreach($id_group as $key => $id)
  {
    $ins[] = "".($id)."";
  }

  $in = implode(",",$ins);

  $sql = "SELECT a.name from `reviews` a 
           INNER JOIN `users` b 
            ON a.id = b.id  
           WHERE a.reply_name = :reply_name 
           AND a.id_group IN (:id_group) 
           ORDER BY a.id_group";

  $users = $dbh->prepare($sql);
  $users->bindValue(':reply_name',$reply_name);
  $users->bindValue(':id_group',$in);
  $users->execute();

  foreach($users as $row)
  {
    echo $row["name"];
  }

1 个答案:

答案 0 :(得分:1)

如错误所示,您无法同时使用:namedParameters?占位符。它要么是,要么从不混合。您必须将所有占位符转换为?并使用位置偏移量绑定所有参数:

$users->bindValue(1, $reply_name);
...
$i = 3;
foreach ($ids as $id) {
    $users->bindValue($i++, $id);
}

// or

$users->execute(array_merge(array($reply_name, $in), $ids));

或者为每个id创建命名占位符:

$placeholders = array_map(function ($num) { return ":id$num"; }, range(1, count($ids)));
$stmt = $pdo->prepare(sprintf('SELECT ... IN (%s)', join(', ', $placeholders)));
// .. bind :id1, :id2 etc. similar to above example