Question

C’est un peu étrange, et je pourrais bien le coder complètement faux. C’est pourquoi j’ai frappé la même erreur deux fois en deux jours, dans des parties complètement différentes d’un script. Le code que j'utilise est ci-dessous:


    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); } }

L’utilisation de PDO est une nouveauté pour moi, mais au fond, je tente de transmettre un tableau de contraintes, par exemple.

array( 'active' => 1, 'name' => 'James' )
et renvoyer toutes les lignes de la table
WHERE active = 1 AND name = 'James'

Si j'utilise ce tableau, le code SQL exécuté à partir de la première

var_dump( )
est
SELECT * FROM {table} WHERE active = :active AND name = 'James'
- exactement comme prévu. Les paramètres liés impriment 'Binding active to 1' et 'Binding name to James' - exactement comme prévu. Les lignes existent dans la base de données et pourtant, le deuxième
var_dump()
appel de $ results ne génère rien - c’est-à-dire qu’aucune ligne n’est renvoyée.

Si je passe un tableau d'une seule contrainte, par exemple.

array( 'active' => 1 )
, cela fonctionne parfaitement. Il semble que, chaque fois que plusieurs contraintes sont passées, cela cesse de fonctionner.

Était-ce utile?

La solution

C'est parce que bindParam fonctionne par une liaison à une variable et que vous réutilisez la variable ( $ value ) pour plusieurs valeurs. Essayez avec bindValue à la place.

Ou même mieux encore; Transmettez les valeurs sous forme de tableau à execute . au lieu. Cela rend la déclaration sans état, ce qui est généralement une bonne chose en programmation.

Autres conseils

Comme mentionné, utilisez bindValue au lieu de bindParam , on y parviendra certainement. Cependant, après avoir passé beaucoup de temps à résoudre ce problème récemment, j'ai découvert une solution alternative. Voici comment effectuer la liaison de variable PDO dans une boucle foreach à l'aide de bindParam:

Remplacez la ligne suivante de la publication d'origine:

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

... avec ceci:

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

Au lieu de lier $ valeur , utilisez $ nom_ array [clé_ray]] . Cela fonctionne parce que vous vous associez maintenant à une variable unique au lieu d’une variable réutilisée à chaque passage de la boucle.

Toutefois, la variable $ field utilisée comme espace réservé ne doit pas nécessairement être unique. Je n'ai pas encore fait de recherches approfondies à ce sujet, mais une variable utilisée comme espace réservé semble être analysée immédiatement (au lieu d'être affectée en tant que référence de variable) même lorsque bindParam est utilisé.

De plus, comme vous n’auriez plus besoin d’accéder directement à $ value , vous pouvez également remplacer ceci:

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

... avec ceci:

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

Ceci est facultatif, car cela fonctionnera correctement sans ce changement. Cela semble plus clair à mon avis cependant, car il pourrait devenir difficile plus tard de savoir pourquoi $ value est assigné mais jamais utilisé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top