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 条评论
登录 后参与评论

相关文章

来自专栏面朝大海春暖花开

springMVC接收参数 xml/json

  如果不一样也可以,通过@RequestParam参数来进行映射下,也是可以设置默认值的

1384
来自专栏开发与安全

linux网络编程之posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序

一、线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属于1:1模型。 (一)、N:1用户线程模型 “线...

3930
来自专栏c#开发者

Asp.net webform scaffolding结合Generic Unit of Work & (Extensible) Repositories Framework代码生成向导

Asp.net webform scaffolding结合Generic Unit of Work & (Extensible) Repositories Fr...

2855
来自专栏二进制文集

Struts1 和 Struts2 对比

参考链接:http://blog.csdn.net/john2522/article/details/7436307

752
来自专栏流柯技术学院

TestNG官方文档中文版(4)-运行TestNG

4 - 运行TestNG TestNG可以以不同的方式调用:     * Command line     * ant     * Eclips...

1082
来自专栏chenssy

【死磕Sharding-jdbc】---基于 SSM 集成sharding-jdbc2.0.3

本篇文章讲解如何在ssm(spring、springmvc、mybatis)结构的程序上集成sharding-jdbc(版本为2.0.3)进行分库分表; 假设分...

751
来自专栏主机笔记

centos安装ab工具给网站进行压力测试

在配置好网站服务器后,我们可以进行压力测试看一看实际环境中的效果怎么样,判断服务器质量、网站程序设计是否合理、提前预防突发事件。今天就介绍一款开源免费的压力测试...

26310
来自专栏服务端技术杂谈

从org.springframework.dao.DuplicateKeyException说起

通常在dao层将所有异常转嫁到Spring的RuntimeException体系(org.springframework.dao.DataAccessExcep...

2054
来自专栏coolblog.xyz技术专栏

MyBatis 源码分析 - 内置数据源

本篇文章将向大家介绍 MyBatis 内置数据源的实现逻辑。搞懂这些数据源的实现,可使大家对数据源有更深入的认识。同时在配置这些数据源时,也会更清楚每种属性的意...

861
来自专栏雪胖纸的玩蛇日常

老男孩Python全栈开发(92天全)视频教程 自学笔记18

1934

扫码关注云+社区