【问题标题】:How to bind multiple values using PDO prepared statements?如何使用 PDO 准备好的语句绑定多个值?
【发布时间】:2025-12-05 13:45:01
【问题描述】:

这是我的代码

$bindParams = [
'name1'  => 'Law',
'name2'  => 'King'
              ];

$sql = "INSERT INTO users (name) VALUES (:name1),(:name2);";

$db->prepared_query($sql,$bindParams);



class Database
{
public function __construct
(
    public \PDO $PDO
)
{}

public function prepared_query(string $sql='',$bindParams=[]): bool
{
    $stmt = $this->PDO->prepare($sql);

    if(count(value:$bindParams) !=0)
    {
        foreach ($bindParams as $k => $v)
        {
            $stmt->bindParam(param:":$k",var:$v);
        }
    }
    $x = $stmt->execute();

    if($x)
    {
        return true;
    }else{
             return false;
         }
    }
}

我面临的问题是,在 foreach 循环中,数组 $bindParams 中具有键 name2 和 value king 的第二个值覆盖了 $stmt->bindParam,并且只有 name2 king 被插入到数据库中。对于每一个插入,我都在数据库中成为王者。这是数据库的屏幕截图。如何在不重复的情况下成功地从数组中插入两条记录。

【问题讨论】:

  • 您应该可以删除foreach 并将参数传递给$x = $stmt->execute($bindParams);
  • @Nigel Ren 我不想传递数组 $bindParams 来执行函数。你能建议我用其他方法为数组的每个键复制这个 $stmt->bindParams() 吗?然后一次尝试对所有这些执行 $stmt->execute() ??
  • 为什么不把它们传递给execute(),这是一种常见的做法?
  • 我想知道反过来只是为了知识..:) @Nigel Ren
  • @Nigel 你能编辑代码并发布吗?

标签: php pdo prepared-statement


【解决方案1】:

您可以简单地传递execute() 中的参数。无需使用bindParam(),它通过引用绑定并会在循环中覆盖您的值。

用这个替换你的代码:

public function prepared_query(string $sql, array $bindParams=[]): void
{
    $stmt = $this->PDO->prepare($sql);
    $stmt->execute($bindParams);
}

如果你真的想要一个你真的不需要的循环,那么你必须按值而不是按引用绑定。例如

public function prepared_query(string $sql, array $bindParams = []): void
{
    $stmt = $this->PDO->prepare($sql);
    foreach ($bindParams as $param => $var) {
        $stmt->bindValue($param, $var);
    }
    $stmt->execute();
}

【讨论】:

  • 我相信空数组和空值一样有效
  • @Dharman $stmt->execute() 假定提供的所有数组值都是 PDO::PARAM_STR 。如果我们将表中的列数据类型设置为 int,然后在这种情况下提供一个字符串值而不是 int,该怎么办?如何使那个 PARAM int??
  • @King619 99.99% 的时间都没有关系。您可以将几乎所有内容绑定为字符串。如果您确实需要将其转换为整数,则可以使用bindValue。这是我提供的第二个例子。