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 htmlspecialchars()与shtmlspecialchars()函数的深入分析
Jun 05 PHP
解决php使用异步调用获取数据时出现(错误c00ce56e导致此项操作无法完成)
Jul 03 PHP
php中文验证码实现示例分享
Jan 12 PHP
php中字符查找函数strpos、strrchr与strpbrk用法
Nov 18 PHP
php curl请求信息和返回信息设置代码实例
Apr 27 PHP
PHP图像处理类库及演示分享
May 17 PHP
php实现遍历多维数组的方法
Nov 25 PHP
PHP中list方法用法示例
Dec 01 PHP
Laravel使用支付宝进行支付的示例代码
Aug 16 PHP
Laravel框架实现redis集群的方法分析
Sep 14 PHP
php获取手机端的号码以及ip地址实例代码
Sep 12 PHP
PDO::errorCode讲解
Jan 28 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
php合并数组array_merge函数运算符加号与的区别
2008/10/31 PHP
php max_execution_time执行时间问题
2011/07/17 PHP
PHP中文分词 自动获取关键词介绍
2012/11/13 PHP
使用php显示搜索引擎来的关键词
2014/02/13 PHP
jQuery+PHP实现的掷色子抽奖游戏实例
2015/01/04 PHP
PHP的命令行命令使用指南
2015/08/18 PHP
php实现登陆模块功能示例
2016/10/20 PHP
php实现微信扫码支付
2017/03/26 PHP
thinkphp 中的volist标签在ajax操作中的特殊性(推荐)
2018/01/15 PHP
SyntaxHighlighter代码加色使用方法
2008/09/07 Javascript
JavaScript入门教程(1) 什么是JS
2009/01/31 Javascript
基于jquery的仿百度的鼠标移入图片抖动效果
2010/09/17 Javascript
简单的ajax连接库分享(不用jquery的ajax)
2014/01/19 Javascript
Javascript中浮点数相乘的一个解决方法
2014/06/03 Javascript
JQuery选中checkbox方法代码实例(全选、反选、全不选)
2015/04/27 Javascript
JavaScript中join()方法的使用简介
2015/06/09 Javascript
javascript实现html页面之间参数传递的四种方法实例分析
2015/12/15 Javascript
JS实现页面中所有img对象添加onclick事件及新窗口查看图片的方法
2016/12/27 Javascript
jQuery用户头像裁剪插件cropbox.js使用详解
2017/06/07 jQuery
Javascript实现的StopWatch功能示例
2017/06/13 Javascript
jQuery实现获取及设置CSS样式操作详解
2018/09/05 jQuery
Nuxt.js实战和配置详解
2019/08/05 Javascript
Vue el-autocomplete远程搜索下拉框并实现自动填充功能(推荐)
2019/10/25 Javascript
vue学习笔记之过滤器的基本使用方法实例分析
2020/02/01 Javascript
关于你不想知道的所有Python3 unicode特性
2014/11/28 Python
python执行等待程序直到第二天零点的方法
2015/04/23 Python
python获取网页中所有图片并筛选指定分辨率的方法
2018/03/31 Python
解决python 3 urllib 没有 urlencode 属性的问题
2019/08/22 Python
python3.8下载及安装步骤详解
2020/01/15 Python
python中wheel的用法整理
2020/06/15 Python
HTML5的video标签的浏览器兼容性增强方案分享
2016/05/19 HTML / CSS
马来西亚最大的电器网站:Senheng
2017/10/13 全球购物
Omio法国:全欧洲低价大巴、火车和航班搜索和比价
2017/11/13 全球购物
园林技术个人的自我评价
2014/01/08 职场文书
打架检讨书400字
2014/01/17 职场文书
留学推荐信英文范文
2015/03/26 职场文书