Quelle est la différence entre bindParam et bindValue?

Réponses:

190

La réponse se trouve dans la documentation de bindParam:

Contrairement à PDOStatement :: bindValue (), la variable est liée comme référence et ne sera évaluée qu'au moment où PDOStatement :: execute () est appelé.

Et execute

appelez PDOStatement :: bindParam () pour lier des variables PHP aux marqueurs de paramètre: les variables liées passent leur valeur en entrée et reçoivent la valeur de sortie, le cas échéant, de leurs marqueurs de paramètre associés

Exemple:

$value = 'foo';
$s = $dbh->prepare('SELECT name FROM bar WHERE baz = :baz');
$s->bindParam(':baz', $value); // use bindParam to bind the variable
$value = 'foobarbaz';
$s->execute(); // executed with WHERE baz = 'foobarbaz'

ou

$value = 'foo';
$s = $dbh->prepare('SELECT name FROM bar WHERE baz = :baz');
$s->bindValue(':baz', $value); // use bindValue to bind the variable's value
$value = 'foobarbaz';
$s->execute(); // executed with WHERE baz = 'foo'
acrosman
la source
667

De l'entrée manuelle pourPDOStatement::bindParam :

[Avec bindParam] Contrairement à PDOStatement::bindValue(), la variable est liée comme référence et ne sera évaluée qu'au moment de l' PDOStatement::execute()appel.

Ainsi, par exemple:

$sex = 'male';
$s = $dbh->prepare('SELECT name FROM students WHERE sex = :sex');
$s->bindParam(':sex', $sex); // use bindParam to bind the variable
$sex = 'female';
$s->execute(); // executed with WHERE sex = 'female'

ou

$sex = 'male';
$s = $dbh->prepare('SELECT name FROM students WHERE sex = :sex');
$s->bindValue(':sex', $sex); // use bindValue to bind the variable's value
$sex = 'female';
$s->execute(); // executed with WHERE sex = 'male'
solitaire
la source
9
Génial, merci! Question - pourquoi voudriez-vous utiliser l'un sur l'autre? Comme quand serait-il utile ou nécessaire de faire évaluer le paramètre de liaison uniquement au moment de execute ()?
Coldblackice
32
@Coldblackice Si vous exécutiez la requête plusieurs fois avec des données différentes. Avec bindValuevous, vous devez à nouveau lier les données à chaque fois. Avec bindParamvous auriez juste besoin de mettre à jour la variable. La principale raison de l'utilisation bindValueserait des données statiques, par exemple des chaînes littérales ou des nombres.
lonesomeday
1
Par exemple, vous souhaitez utiliser bindValue avec des valeurs de retour de fonction: $ stmt-> bindValue (': status', strtolower ($ status), PDO :: PARAM_STR);
paidforbychrist
1
voulait voter, mais parce qu'il est 666, je vais le laisser
eddy147
219

En voici quelques-unes auxquelles je peux penser:

  • Avec bindParam, vous ne pouvez transmettre que des variables; pas des valeurs
  • avec bindValue, vous pouvez passer les deux (valeurs, évidemment, et variables)
  • bindParamne fonctionne qu'avec des variables car il permet de donner des paramètres en entrée / sortie, par "référence" (et une valeur n'est pas une "référence" valide en PHP) : elle est utile avec les drivers qui (en citant le manuel):

prendre en charge l'invocation de procédures stockées qui renvoient des données en tant que paramètres de sortie, et certaines également en tant que paramètres d'entrée / sortie qui envoient des données et sont mises à jour pour les recevoir.

Avec certains moteurs de base de données, les procédures stockées peuvent avoir des paramètres qui peuvent être utilisés à la fois pour l'entrée (donnant une valeur de PHP à la procédure) et pour la sortie (retournant une valeur du proc stocké à PHP); pour lier ces paramètres, vous devez utiliser bindParam et non bindValue.

Pascal MARTIN
la source
@PascalMartin Juste ce que je voulais savoir, pouvez-vous lier des valeurs avec bindParam. À votre santé.
yehuda
1
Je n'ai toujours aucune idée de ce que cela signifie exactement, quelles sont exactement les variables et quelles sont les valeurs. J'utilise bindParam pour lier une valeur à un espace réservé et avec bindValue je peux faire la même chose! - dans mon exemple au moins ...
Richard
29

À partir des instructions préparées et des procédures stockées

Utilisez bindParampour insérer plusieurs lignes avec une liaison unique:

<?php

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);

// insert one row
$name = 'one';
$value = 1;
$stmt->execute();

// insert another row with different values
$name = 'two';
$value = 2;
$stmt->execute();
Nezar Fadle
la source
27

Pour le but le plus courant, vous devez utiliser bindValue.

bindParam a deux comportements délicats ou inattendus:

  • bindParam(':foo', 4, PDO::PARAM_INT) ne fonctionne pas, car il nécessite de passer une variable (comme référence).
  • bindParam(':foo', $value, PDO::PARAM_INT)changera $valueen chaîne après l'exécution execute(). Bien sûr, cela peut conduire à des bogues subtils qui pourraient être difficiles à détecter.

Source: http://php.net/manual/en/pdostatement.bindparam.php#94711

Denilson Sá Maia
la source
4

Vous n'avez plus à vous battre, quand il existe un moyen de le faire:

$stmt = $pdo->prepare("SELECT * FROM someTable WHERE col = :val");
$stmt->execute([":val" => $bind]); 
Thielicious
la source
4

La façon la plus simple de mettre cela en perspective pour la mémorisation par comportement (en termes de PHP):

  • bindParam: référence
  • bindValue: variable
tfont
la source