PHP PDOStatement:bindParam插入数据错误问题分析

开发技术 作者: 2024-08-07 23:50:01
PHP PDOStatement:bindParam插入数据错误问题分析,开发中一定要注意

废话不多说,直接看代码:
<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的时候,谨慎!

原创声明
本站部分文章基于互联网的整理,我们会把真正“有用/优质”的文章整理提供给各位开发者。本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
本文链接:http://www.jiecseo.com/news/show_58295.html
PHP PDOStatement bindParam

本站采用系统自动发货方式,付款后即出现下载入口,如有疑问请咨询在线客服!

售后时间:早10点 - 晚11:30点

咨询售后客服

推荐精华