PHP PDO: Binding 9 variables and giving 9 tokes throws an 'Invalid parameter number: number of bound variables does not match number of tokens' error?

问题描述 投票:0回答:0

我正在尝试扩展一些继承的代码以将对象的第二个属性保存到使用的 sql 数据库中。我仍然习惯于 php,之前从未使用过 PDO,所以我对所看到的行为感到非常困惑。 原代码为:

$places = $petrinet->getPlaces();
$values = implode(", ", array_map(function($place) {
    sprintf("(:pid, :%sname)", 
    $place->getID());
    }, $places->toArray()));
$query = sprintf("INSERT INTO %s (`petrinet`, `name`) VALUES %s",
    ['PETRINET_PLACE_TABLE'], $values);
$statement = $this->db->prepare($query);
$statement->bindParam(":pid", $pid, PDO::PARAM_INT);
foreach($places as $place){
     $statement->bindValue(sprintf(":%sname", $place), $place, PDO::PARAM_STR);
     }
$statement->execute();

我希望,为了扩展它,我可以简单地将标签变量添加到值、查询并编写另一个 bindValue,因此我这样写:

$places = $petrinet->getPlaces();
$values = implode(", ", array_map(function($place) {
    sprintf("(:pid, :%sname, :%slabel)", 
    $place->getID()
    $place->getLabel());
    }, $places->toArray()));
$query = sprintf("INSERT INTO %s (`petrinet`, `name`, `label`) VALUES %s",
    ['PETRINET_PLACE_TABLE'], $values);
$statement = $this->db->prepare($query);
$statement->bindParam(":pid", $pid, PDO::PARAM_INT);
foreach($places as $place){
     $statement->bindValue(sprintf(":%sname", $place->getID()), $place->getID(), PDO::PARAM_STR);
     $statement->bindValue(sprintf(":%slabel", $place->getLabel()), $place->getLabel(), PDO::PARAM_STR);
     }
$statement->execute();

然而,这总是给出一个

Invalid parameter number: number of bound variables does not match number of tokens

由于某种原因我不太明白的错误。

我已经使用最初返回的 PDO

debugDumpParams()
函数转储了所有信息:

    back_end_1  | Params:  5    
back_end_1  | Key: Name: [4] :pid   
back_end_1  | paramno=-1    
back_end_1  | name=[4] ":pid"   
back_end_1  | is_param=1    
back_end_1  | param_type=1  
back_end_1  | Key: Name: [7] :p1name    
back_end_1  | paramno=-1    
back_end_1  | name=[7] ":p1name"    
back_end_1  | is_param=1    
back_end_1  | param_type=2  
back_end_1  | Key: Name: [7] :p2name    
back_end_1  | paramno=-1    
back_end_1  | name=[7] ":p2name"    
back_end_1  | is_param=1    
back_end_1  | param_type=2  
back_end_1  | Key: Name: [7] :p3name    
back_end_1  | paramno=-1    
back_end_1  | name=[7] ":p3name"    
back_end_1  | is_param=1    
back_end_1  | param_type=2  
back_end_1  | Key: Name: [7] :p4name    
back_end_1  | paramno=-1    
back_end_1  | name=[7] ":p4name"    
back_end_1  | is_param=1    
back_end_1  | param_type=2

正如预期的那样,但是当扩展它时返回:

back_end_1  | Params:  9
back_end_1  | Key: Name: [4] :pid
back_end_1  | paramno=-1
back_end_1  | name=[4] ":pid"
back_end_1  | is_param=1
back_end_1  | param_type=1
back_end_1  | Key: Name: [7] :p1name
back_end_1  | paramno=-1
back_end_1  | name=[7] ":p1name"
back_end_1  | is_param=1
back_end_1  | param_type=2
back_end_1  | Key: Name: [24] :Frogslabel
back_end_1  | paramno=-1
back_end_1  | name=[24] ":Frogslabel"
back_end_1  | is_param=1
back_end_1  | param_type=2
back_end_1  | Key: Name: [7] :p2name
back_end_1  | paramno=-1
back_end_1  | name=[7] ":p2name"
back_end_1  | is_param=1
back_end_1  | param_type=2
back_end_1  | Key: Name: [18] :Riverlabel
back_end_1  | paramno=-1
back_end_1  | name=[18] ":Riverlabel"
back_end_1  | is_param=1
back_end_1  | param_type=2
back_end_1  | Key: Name: [7] :p3name
back_end_1  | paramno=-1
back_end_1  | name=[7] ":p3name"
back_end_1  | is_param=1
back_end_1  | param_type=2
back_end_1  | Key: Name: [13] :Counterlabel
back_end_1  | paramno=-1
back_end_1  | name=[13] ":Counterlabel"
back_end_1  | is_param=1
back_end_1  | param_type=2
back_end_1  | Key: Name: [7] :p4name
back_end_1  | paramno=-1
back_end_1  | name=[7] ":p4name"
back_end_1  | is_param=1
back_end_1  | param_type=2
back_end_1  | Key: Name: [14] :Counter2label
back_end_1  | paramno=-1
back_end_1  | name=[14] ":Counter2label"
back_end_1  | is_param=1
back_end_1  | param_type=2

据我所知,究竟应该发生什么? 过去的 5 个变量(pid + 4 个名称)被另外 4 个变量(pid + 4 个名称 + 4 个标签)扩展。有没有人能够提供一些关于为什么会发生这种情况的见解?

有趣的是,即使对值进行硬编码仍然会引发错误(仅包含修改后的代码::

$values2 = '(:pid, :p1name, :counter1label), (:pid, :p2name, :counter2label), (:pid, :p3name, :counter3label), (:pid, :p4name, :counter4label)';
$query = sprintf("INSERT INTO %s (`petrinet`, `name`, `label`) VALUES %s",
                $_ENV['PETRINET_PLACE_TABLE'], $values2);
$statement->bindParam(":pid", $pid, PDO::PARAM_INT);
foreach($places as $place){
   $statement->bindValue(sprintf(":%sname", $place->getID()), $place->getID(), PDO::PARAM_STR);
}        
foreach($anArray as $elem){
   $statement->bindValue(sprintf(":%slabel", $elem), $elem, PDO::PARAM_STR);
}

我在这里完全不知所措

php sql pdo
© www.soinside.com 2019 - 2024. All rights reserved.