PHP开发过程的那些坑(四) ——PDO bindParam函数

PHP开发过程的那些坑(四)——PDO bindParam函数

(原创内容,转载请注明来源,谢谢)

坑:

bindParam是PDOStatement的一个方法,用于在PDO操作中绑定占位符的内容,进行替换,是PDO安全性的一大保障。

通常用法如下:(摘自PHP官方文档)

<?php
/* 通过绑定的 PHP 变量执行一条预处理语句  */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>

可以看到,通过bindParam方法,可以把calories和colour替换成上面的变量。这个对防止sql注入具有重要作用。

但是,最近我遇到的问题是,通常绑定的内容很多个,可以用foreach来实现,我也就写了一个方法,如下:

//绑定sql(错误的方式)
private functionbindSql($query, $arrData){
//注:arrData=array(col1=>val1,col2=>val2…)
         if(empty($arrData)){
                  returnnull;
         }else{
                  foreach($arrDataas $col => $val){
                            $col= ':'.$col;
                            $query->bindParam($col, $val);
                  }
                  return$query;
         }                          
}

但是,当我调用这个方法时,发现如果arrData只有一个参数时,正常运行,但是当传入两个或者以上时,就出问题了,最后绑定的内容全部变成最后一个val了。

经过我多次和原例子比对,发现没有问题,百思不得其解,只能再次看官方文档,直到我看到了这个人的留言:(摘自PHP官方文档)

瞬间恍然大悟。需要在$val前面加一个取地址符号&。

分析:

再次认真查看官方文档,发现其对bindParam的定义如下:(摘自官方文档)

bool PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type =PDO::PARAM_STR [, int$length [, mixed $driver_options ]]] )

注意查看第二个参数 mixed &$variable,发现有个取地址符号。即此参数是引用绑定,在最终执行sql时才会真正被取值。

因此,单条的使用bindParam(包括连续好几行都是这个,类似官方文档)可以不用取地址符号,因为每次用不同的变量,则取不同的地址。而如果用foreach时,必须使用&符号,否则随着foreach的迭代,会被取到最后一个内容当作结果。

改进措施:

加上取地址符即可。

//绑定sql(正确的方式)
private functionbindSql($query, $arrData){
//注:arrData=array(col1=>val1,col2=>val2…)
         if(empty($arrData)){
                  returnnull;
         }else{
                  foreach($arrDataas $col => &$val){
                            $col= ':'.$col;
                            $query->bindParam($col, $val);
                  }
                  return$query;
         }                          
}

——written by linhxx 2017.07.25

相关阅读:

PHP开发过程的那些坑(三) ——PHParray_shift函数

PHP开发过程的那些坑(二) ——PHP empty函数

PHP开发过程的那些坑(一) ——对象拷贝

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-07-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

linux实用技巧:你该使用ctags查找源码了

linux实用技巧:你该使用ctags查找源码了 ---- 1.ctags简介: “哦,这个多的文件,我该如何去查看XX函数的实现!”相信...

2636
来自专栏用户画像

python excel转txt文件

672
来自专栏程序员互动联盟

【入门必备】编程必备技能--抓出代码中的蛀虫

很多的朋友,在写代码的时候经常运行出错然而却找不到哪里错了。那就是你没有学会分析错误,你到底错在哪里了?为什么错了? 第一种代码致命错误。 一般的错误代码在编译...

2576
来自专栏Python小屋

Python编程常见出错信息及原因分析(1)

1.被0除错误 演示代码: >>> 2 / 0 Traceback (most recent call last): File "<pyshell#0>",...

2766
来自专栏LanceToBigData

linux(四)之元字符

一直觉得linux是一个非常高深的东西,但是慢慢学过来其实就是一堆一堆的命令执行,让一个程序运行的结果。 只有你有毅力去学习,并且系统的去学习我相信没有什么恶...

1857
来自专栏Vamei实验室

Python补充02 Python小技巧

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢! 在这里列举一些我使用Python时积累的小...

1777
来自专栏小樱的经验随笔

【批处理学习笔记】第四课:简单批处理命令(3)

call 命令   CALL命令可以在批处理执行过程中调用另一个批处理,当另一个批处理执行完后,再继续执行原来的批处理 CALL command 调用一条批处理...

2637
来自专栏IMWeb前端团队

教你做一个异步的fis3插件

本文作者:IMWeb 黄龙 原文出处:IMWeb社区 未经同意,禁止转载 不清楚fis3是什么的可以先看这个链接 http://fis.baidu.c...

1779
来自专栏架构说

c++在编译中遇到符合不存在如何解决?

今日问题:symbol 不存在 : symbol lookup error: ./libinterface.so: undefined symbol: _ZN...

32815
来自专栏orientlu

叙述 C语言编译

工作原因有时候会用python写写测试工具,感受到其快速实现应用的便利,但由于偏底层开发,主力语言依然是C。对于开发语言没有什么优劣概念,在特定的情景下哪种实现...

301

扫描关注云+社区