废话不多说,直接看代码: <div class="codetitle"><a style="CURSOR: pointer" data="99033" class="copybut" id="copybut99033" onclick="doCopy('code99033')"> 代码如下:<div class="codebody" id="code99033"> <?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();
请问,最终执行的SQL语句是什么,上面的代码是否有什么问题? Okey,我想大部分同学会认为,最终执行的SQL是: INSERT INTO user (username ,password ) VALUES ("laruence","weibo"); 但是,可惜的是,你错了,password ) VALUES ("weibo","weibo"); 是不是很大的一个坑呢? 这个问题,来自今天的一个Bug报告: #63281 究其原因,也就是bindParam和bindValue的不同之处,bindParam要求第二个参数是一个引用变量(reference). 让我们把上面的代码的foreach拆开,也就是这个foreach: <div class="codetitle"><a style="CURSOR: pointer" data="90747" class="copybut" id="copybut90747" onclick="doCopy('code90747')"> 代码如下:<div class="codebody" id="code90747"> <?php foreach( $bind_params as $key => $value ){ $statement->bindParam($key,$value); }
相当于: <div class="codetitle"><a style="CURSOR: pointer" data="68721" class="copybut" id="copybut68721" onclick="doCopy('code68721')"> 代码如下:<div class="codebody" id="code68721"> <?php //第一次循环 $value = $bind_params[":username"]; $statement->bindParam(":username",&$value); //此时,:username是对$value变量的引用//第二次循环 $value = $bind_params[":password"]; //oops! $value被覆盖成了:password的值 $statement->bindParam(":password",&$value);
所以,在使用bindParam的时候,尤其要注意和foreach联合使用的这个陷阱. 那么正确的作法呢? 1. 不要使用foreach,而是手动赋值 <div class="codetitle"><a style="CURSOR: pointer" data="8242" class="copybut" id="copybut8242" onclick="doCopy('code8242')"> 代码如下:<div class="codebody" id="code8242"> <?php $statement->bindParam(":username",$bind_params[":username"]); //$value是引用变量了 $statement->bindParam(":password",$bind_params[":password"]);
2. 使用bindValue代替bindParam,或者直接在execute中传递整个参数数组. 3. 使用foreach和reference(不推荐) <div class="codetitle"><a style="CURSOR: pointer" data="89679" class="copybut" id="copybut89679" onclick="doCopy('code89679')"> 代码如下:<div class="codebody" id="code89679"> <?php foreach( $bind_params as $key => &$value ) { //注意这里 $statement->bindParam($key,$value); }
最后,展开了说,对于要求参数是引用,并且有滞后处理的函数,都要在使用foreach的时候,谨慎! (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|