2

这有点奇怪,我很可能完全错误地编写了这个代码 - 因此我在两天内两次在脚本的完全不同部分遇到了相同的错误。我正在使用的代码如下:


    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'

如果我使用这个数组,则从第一个执行的 SQL

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

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

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

4

2 回答 2

10

那是因为bindParam通过绑定到变量来工作,并且您正在将变量 ( $value) 重新用于多个值。尝试使用bindValue

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

于 2008-09-28T22:43:30.623 回答
0

如前所述,使用bindValue而不是bindParam肯定会实现这一点。然而,在最近花了相当多的时间解决这个问题之后,我发现了一个替代解决方案。下面是如何使用 bindParam 在 foreach 循环中完成 PDO 变量绑定:

替换原始帖子中的以下行:

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

...有了这个:

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

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

然而,用作占位符的变量$field显然不需要是唯一变量。我尚未对此进行彻底研究,但即使使用 bindParam,用作占位符的变量似乎也会立即被解析(而不是被分配为变量引用)。

此外,由于您不再需要$value直接访问,您也可以替换它:

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

... 有了这个:

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

这是可选的,因为没有此更改它可以正常工作。不过,在我看来,它看起来更干净,因为它可能会在稍后为什么$value被分配但从未使用过的问题上变得混乱。

于 2014-12-26T05:48:15.650 回答