Maison  >  Article  >  développement back-end  >  Regarder! Il y a un piège avec PDOStatement::bindParam !

Regarder! Il y a un piège avec PDOStatement::bindParam !

藏色散人
藏色散人avant
2020-11-20 15:35:5511801parcourir

Recommandé : "Tutoriel vidéo PHP"

Plus de bêtises, regardez simplement le code :

<?php
$dbh = new PDO(&#39;mysql:host=localhost;dbname=test&#39;, "test");
$query = <<<query
  INSERT INTO `user` (`username`, `password`) VALUES (:username, :password);
QUERY;
$statement = $dbh->prepare($query);
$bind_params = array(&#39;:username&#39; => "laruence", &#39;:password&#39; => "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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer