Maison > Article > développement back-end > Regarder! Il y a un piège avec PDOStatement::bindParam !
Recommandé : "Tutoriel vidéo PHP"
Plus de bêtises, regardez simplement le code :
<?php $dbh = new PDO('mysql:host=localhost;dbname=test', "test"); $query = <<<query INSERT INTO `user` (`username`, `password`) VALUES (:username, :password); QUERY; $statement = $dbh->prepare($query); $bind_params = array(':username' => "laruence", ':password' => "weibo"); foreach( $bind_params as $key => $value ){ $statement->bindParam($key, $value); } $statement->execute();
Excusez-moi, quelle est l'instruction SQL finale exécutée ci-dessus ? Y a-t-il un problème avec le code ?
Ok, je pense que la plupart des étudiants penseront que le SQL final exécuté est :
INSERT INTO `user` (`username`, `password`) VALUES ("laruence", "weibo");
Mais, malheureusement, vous vous trompez, le SQL final exécuté est :
INSERT INTO `user` (`username`, `password`) VALUES ("weibo", "weibo");
N'est-ce pas un gros piège ?
------ Si vous voulez trouver la raison vous-même, alors ne continuez pas à lire------ - --
Ce problème vient d'un rapport de bug aujourd'hui : #63281
La raison est que la différence entre bindParam et bindValue est que bindParam nécessite que le deuxième paramètre soit une variable de référence (référence) .
Démontons le foreach du code ci-dessus, c'est-à-dire que ce foreach :
<?php foreach( $bind_params as $key => $value ){ $statement->bindParam($key, $value); }
est équivalent à :
<?php //第一次循环 $value = $bind_params[":username"]; $statement->bindParam(":username", &$value); //此时, :username是对$value变量的引用 //第二次循环 $value = $bind_params[":password"]; //oops! $value被覆盖成了:password的值 $statement->bindParam(":password", &$value);
Donc, lors de l'utilisation de bindParam Lors de son utilisation, vous devez prêter une attention particulière à ce piège lorsqu'il est utilisé avec foreach. Alors, quelle est la bonne approche ?
1. N'utilisez pas foreach, mais attribuez des valeurs manuellement
<?php $statement->bindParam(":username", $bind_params[":username"]); //$value是引用变量了 $statement->bindParam(":password", $bind_params[":password"]);
2. . Utilisez bindValue au lieu de bindParam, ou transmettez l'intégralité du tableau de paramètres directement dans l'exécution.
3 Utilisez foreach et reference (non recommandé, voir Weibo pour la raison)
<?php foreach( $bind_params as $key => &$value ) { //注意这里 $statement->bindParam($key, $value); }
Enfin, développez et. disons que les paramètres requis sont des références, Et pour les fonctions avec traitement de décalage, soyez prudent lorsque vous utilisez foreach !
Adresse originale : https://www.laruence.com/2012/10/16/2831 .html
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!