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


Posted in PHP onNovember 13, 2013

废话不多说, 直接看代码:

<?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");
但是, 可惜的是, 你错了, 最终执行的SQL是:
INSERT INTO `user` (`username`, `password`) VALUES ("weibo", "weibo");
是不是很大的一个坑呢?
这个问题, 来自今天的一个Bug报告: #63281
究其原因, 也就是bindParam和bindValue的不同之处, bindParam要求第二个参数是一个引用变量(reference).
让我们把上面的代码的foreach拆开, 也就是这个foreach:
<?php
foreach( $bind_params as $key => $value ){
    $statement->bindParam($key, $value);
}

相当于:
<?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, 而是手动赋值
<?php
$statement->bindParam(":username", $bind_params[":username"]); //$value是引用变量了
$statement->bindParam(":password", $bind_params[":password"]);

2. 使用bindValue代替bindParam, 或者直接在execute中传递整个参数数组.
3. 使用foreach和reference(不推荐)
<?php
foreach( $bind_params as $key => &$value ) { //注意这里
    $statement->bindParam($key, $value);
}

最后, 展开了说, 对于要求参数是引用, 并且有滞后处理的函数, 都要在使用foreach的时候, 谨慎!
PHP 相关文章推荐
PHP分页显示制作详细讲解
Oct 09 PHP
自己前几天写的无限分类类
Feb 14 PHP
php实现jQuery扩展函数
Oct 30 PHP
php下将XML转换为数组
Jan 01 PHP
php导出word文档与excel电子表格的简单示例代码
Mar 08 PHP
让ThinkPHP支持大小写url地址访问的方法
Oct 31 PHP
php输出指定时间以前时间格式的方法
Mar 21 PHP
dvwa+xampp搭建显示乱码的问题及解决方案
Aug 23 PHP
简单PHP会话(session)说明介绍
Aug 21 PHP
PHP验证终端类型是否为手机的简单实例
Feb 07 PHP
PHP中define() 与 const定义常量的区别详解
Jun 25 PHP
yii2.0框架数据库操作简单示例【添加,修改,删除,查询,打印等】
Apr 13 PHP
php curl模拟post请求小实例
Nov 13 #PHP
CodeIgniter生成网站sitemap地图的方法
Nov 13 #PHP
php模板原理讲解
Nov 13 #PHP
php构造函数实例讲解
Nov 13 #PHP
PHP将XML转数组过程详解
Nov 13 #PHP
PHP生成sitemap.xml地图函数
Nov 13 #PHP
使用PHP静态变量当缓存的方法
Nov 13 #PHP
You might like
《Re:从零开始的异世界生活》剧情体验,手游新作定名
2020/04/09 日漫
php中截取字符串支持utf-8
2007/01/18 PHP
PHP 循环列出目录内容的函数代码
2010/05/26 PHP
php表单转换textarea换行符的方法
2010/09/10 PHP
PHP实现批量生成App各种尺寸Logo
2015/03/19 PHP
利用php操作memcache缓存的基础方法示例
2017/08/02 PHP
PHP cookie,session的使用与用户自动登录功能实现方法分析
2019/06/05 PHP
PHPUnit + Laravel单元测试常用技能
2019/11/06 PHP
JavaScript中null与undefined分析
2009/07/25 Javascript
Web跨浏览器进程通信(Web跨域)
2013/04/17 Javascript
AngularJS 2.0新特性有哪些
2016/02/18 Javascript
下雪了 javascript实现雪花飞舞
2020/08/02 Javascript
JS中正则表达式只有3种匹配模式(没有单行模式)详解
2016/07/28 Javascript
Bootstrap源码解读模态弹出框(11)
2016/12/28 Javascript
Bootstrap实现的经典栅格布局效果实例【附demo源码】
2017/03/30 Javascript
微信小程序框架wepy之动态控制类名
2018/09/14 Javascript
小程序getLocation需要在app.json中声明permission字段
2019/04/04 Javascript
vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip
2020/06/02 Javascript
Python模块学习 datetime介绍
2012/08/27 Python
python tkinter库实现气泡屏保和锁屏
2019/07/29 Python
Django中使用session保持用户登陆连接的例子
2019/08/06 Python
python使用梯度下降和牛顿法寻找Rosenbrock函数最小值实例
2020/04/02 Python
Meli Melo官网:名媛们钟爱的英国奢侈手包品牌
2017/04/17 全球购物
大一学生的职业生涯规划书范文
2014/01/19 职场文书
行政文秘岗位职责范本
2014/02/10 职场文书
管理学院毕业生自荐信范文
2014/03/10 职场文书
法律系毕业生自荐信范文
2014/03/27 职场文书
幼儿园老师寄语
2014/04/03 职场文书
财政局党的群众路线教育实践活动剖析材料
2014/10/13 职场文书
民主评议党员工作总结
2014/10/20 职场文书
先进基层党组织材料
2014/12/25 职场文书
倡议书的格式写法
2015/04/28 职场文书
消防宣传标语大全
2015/08/03 职场文书
2016年主题党日活动总结
2016/04/05 职场文书
Python 中的Sympy详细使用
2021/08/07 Python
Java8利用Stream对列表进行去除重复的方法详解
2022/04/14 Java/Android