質問
これは少し奇妙なもので、これを完全に間違ってコーディングしている可能性があります。したがって、スクリプトのまったく異なる部分で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 )
、これは完璧に機能します。複数の制約が渡されると、動作が停止するようです。
他のヒント
前述のとおり、 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
が割り当てられているが使用されていない理由については後で混乱する可能性があるため、私の意見ではよりきれいに見えます。