Fehler bei bindParam Überschreiben in PHP
Frage
Dies ist ein bisschen wie ein seltsam, und ich konnte auch diese völlig falsch seine Codierung - also warum ich den gleichen Fehler zweimal in zwei Tagen getroffen habe, in ganz verschiedenen Teilen eines Skripts. Der Code Ich verwende unter:
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);
}
}
Ich bin ziemlich neu PDO zu verwenden, aber im Grunde ich bin versucht, eine Reihe von Einschränkungen passiert z.B.
array( 'active' => 1, 'name' => 'James' )
und kehren alle Zeilen aus der Tabelle WHERE active = 1 AND name = 'James'
Wenn ich dieses Array, die SQL ausgeführt von der ersten
var_dump( )
SELECT * FROM {table} WHERE active = :active AND name = 'James'
wird - genau so, wie ich erwartet. Die gebundenen Parameter druckt ‚Binding aktiv 1‘ und ‚Binding Namen James‘ - genau wie erwartet. Die Zeilen in der Datenbank vorhanden, und doch ist der zweite var_dump()
Aufruf für nichts $ Ergebnisse gibt - das heißt keine Zeilen zurückgegeben .
I Wenn ein Array von einer einzigen Einschränkung passieren, z.B.
array( 'active' => 1 )
funktioniert das völlig in Ordnung. Es erscheint immer dann, wenn mehrere Einschränkungen sind vergangen zu sein, dass es nicht mehr funktioniert.
Lösung
Das ist, weil bindParam
funktioniert, indem auf eine Variable zu binden, und Sie die Variable ($value
) für mehrere Werte werden wieder verwendet. Versuchen Sie, mit bindValue
statt.
Oder sogar noch besser; Übergeben, die Werte als Array zu execute
statt. Dies macht die Aussage staatenlos, die im Allgemeinen eine gute Sache in der Programmierung ist.
Andere Tipps
Wie bereits erwähnt, mit bindValue
anstelle von bindParam
wird dies sicherlich erreichen. Nachdem jedoch eine beträchtliche Menge an Zeit zur Fehlerbehebung dieses Problem vor kurzem verbrachte, entdeckte ich eine alternative Lösung. Hier ist, wie PDO variable Bindung in einer foreach-Schleife mit bindParam zu erreichen:
Ersetzen Sie die folgende Zeile aus dem Original-Beitrag:
$PDOStatement->bindParam( $field, $value );
... mit dieser:
$PDOStatement->bindParam( $field, $constraints[$field] );
Statt Bindung $value
, Verwendung $array_name[$array_key]
. Dies funktioniert, weil Sie jetzt eine einzigartige variable Bindung statt einer, die bei jedem Durchlauf der Schleife wiederverwendet wird.
Die Variable $field
verwendet als der Platzhalter offenbar keine eindeutige Variable sein muss, jedoch. Ich habe nicht gründlich dies noch erforscht, aber eine Variable als Platzhalter verwendet wird sofort analysiert werden (anstatt als Variable Referenz zugeordnet ist), selbst wenn bindParam verwendet wird.
Auch, wie Sie nicht mehr brauchen würden $value
direkt zugreifen zu können, können Sie auch diese ersetzen:
foreach( $constraints as $field => $value ) {
... mit dieser:
foreach (array_keys($constraints) as $field) {
Dies ist optional, da es ohne diese Änderung gut funktionieren wird. Es sieht sauberer meiner Meinung nach aber, da es später verwirrend könnte, warum $value
zugewiesen wird, aber nie benutzt.