質問

これは少し奇妙なもので、これを完全に間違ってコーディングしている可能性があります。したがって、スクリプトのまったく異なる部分で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'

この配列を使用する場合、最初の

var_dump( )
から実行されるSQLは
SELECT * FROM {table} WHERE active = :active AND name = 'James'
-予想どおりです。バインドされたパラメータは、「Binding active to 1」と「Binding name to James」を印刷します-予想どおり。行はデータベースに存在しますが、$ resultsの2回目の
var_dump()
呼び出しでは何も出力されません-つまり、行は返されません。

単一の制約の配列を渡すと、たとえば

array( 'active' => 1 )
、これは完璧に機能します。複数の制約が渡されると、動作が停止するようです。

役に立ちましたか?

解決

それは、 bindParam が動作するためです変数にバインドし、複数の値に対して変数( $ value )を再利用しています。代わりに bindValue を試してください。

またはさらに良い。値を配列として execute に渡します代わりに。これにより、ステートメントがステートレスになります。これは、一般的にプログラミングで良いことです。

他のヒント

前述のとおり、 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 が割り当てられているが使用されていない理由については後で混乱する可能性があるため、私の意見ではよりきれいに見えます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top