2

これは少し奇妙で、これを完全に間違ってコーディングしている可能性があります。そのため、スクリプトのまったく異なる部分で、2 日間で 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」を正確に出力します。行はデータベースに存在しますが、2 番目の行は
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 に答える