2008-09-28 31 views
2

这有些奇怪,我完全可以将它编码为完全错误的 - 因此,为什么我在两天内在脚本的完全不同部分碰到了相同的错误两次。我使用的代码如下:在PHP中bindParam覆盖错误


    public function findAll($constraints = array()) { 

     // Select all records 
     $SQL = 'SELECT * FROM ' . $this->tableName; 

     // See if there's any constraints 
     if(count($constraints) > 0) { 
      $SQL .= ' WHERE '; 

      foreach($constraints as $field => $value) { 
       $SQL .= $field . ' = :' . $field . ' AND '; 
      } 

     } 

     // Remove the final AND and prepare the statement 
     $SQL = substr($SQL, 0, -5);  
     $PDOStatement = $this->PDO->prepare($SQL); 

     // Loop through constraints and bind parameters 
     foreach($constraints as $field => $value) { 
      print 'Binding ' . $field . ' to ' . $value . ' 
'; $PDOStatement->bindParam($field, $value); } $PDOStatement->execute(); var_dump($PDOStatement); while ($results = $PDOStatement->fetch(PDO::FETCH_ASSOC)) { var_dump($results); } }

我很新使用PDO,但基本上我试图传递一个约束数组,

array('active' => 1, 'name' => 'James')
从桌上
WHERE active = 1 AND name = 'James'

返回所有行如果我用这个阵,从第一

var_dump()
执行的SQL是
SELECT * FROM {table} WHERE active = :active AND name = 'James'
- 正是我期望的那样。绑定的参数打印出'Binding active to 1'和'Binding name to James' - 完全如预期。这些行存在于数据库中,但第二个调用$ results的内容不会输出 - 即不返回任何行。

如果我传递一个单个约束的数组,例如

array('active' => 1)
,这工作非常好。似乎只要通过多个约束就会停止工作。

回答

9

这是因为bindParam通过绑定到一个变量来工作,并且您正在重新使用变量($value)获取多个值。改为使用bindValue

甚至更​​好;改为将值作为数组传递到execute。这使得语句无状态,这在编程中通常是一件好事。

0

如前所述,使用bindValue而不是bindParam肯定会做到这一点。但是,在最近花费大量时间解决这个问题之后,我发现了另一种解决方案。下面是如何完成PDO变量使用bindParam在foreach循环绑定:

更换从原来的职位下面一行:

$PDOStatement->bindParam($field, $value); 

...这一点:

$PDOStatement->bindParam($field, $constraints[$field]); 

代替绑定$value,使用$array_name[$array_key]。这是有效的,因为你现在绑定到一个唯一的变量,而不是在循环的每次传递中被重用的变量。

然而,用作占位符的变量$field显然不需要是唯一变量。我还没有深入研究过这个问题,但是即使在使用bindParam的时候,一个用作占位符的变量也会立即被解析(而不是被指定为变量引用)。与此

foreach($constraints as $field => $value) { 

...:

而且,你将不再需要直接访问$value,你也可以更换此

foreach (array_keys($constraints) as $field) { 

这是可选的,因为它会没有这个改变就能正常工作尽管如此,我认为它看起来更干净,因为它可能会在以后为什么$value被分配但从未使用过后感到困惑。