ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

PHP-PDO参数绑定问题

2021-10-02 16:00:22  阅读:234  来源: 互联网

标签:username key 绑定 value PDO foreach statement PHP data


前言

今天在执行这样一段代码:

$data = [
    'username' => 'hujingnb',
    'address' => 'beijing',
];
$dbh = new PDO("mysql:host={$host};dbname={$dbname}", $username, $password);
$statement = $dbh->prepare('INSERT INTO `test_user` (`username`, `address`) VALUES (:username, :address)');
foreach($data as $key => $value ){
    $statement->bindParam($key, $value);
}
$ret = $statement->execute();

这意思很明显了嘛. 但是, 当我看到插入的数据内容时, 我傻眼了.

image-20211002152751240

什么? 为什么会这样, 一共就5行代码, 我哪里写的有问题?

解惑

最终, 还是编译器救了我. 我看到了这个:

image-20211002152944648

注意我圈中的地方, 也就是说, 这个方法接了一个引用的值. 这样我想起了之前遇到的一个相同的坑, 具体可看我这篇文章: PHP 循环引用的问题

简单来说, 就是bindParam方法, 接到$value变量的地址存起来了, 每次循环拿到的都是同一个地址. 等到循环结束的时候, $value所指定的值为数组的最后一个, 此时, statement对象中记录的所有$value自然也都是数组最后一个. 插入数据全部为'beijing'也就不奇怪了.

解决

既然知道了问题出在地址引用上, 解决的思路就放在地址的引用上了. 怎么解决呢?

1. unset

每次循环结束时, 都调用unset方法, 将$value释放调, 这样下次进入循环是,又是一个新的变量了.

foreach($data as $key => $value ){
    $statement->bindParam($key, $value);
    unset($value);
}

2. 将遍历去掉

不使用foreach, 直接进行赋值, 这样也就没有中间变量的问题拉.

$statement->bindValue(":username", $data['username']);
$statement->bindValue(":address", $data['address']);

3.使用引用接

foreach中, 直接用引用接$value的内容, 这样接到的本身, 就是数据value的引用对象, 每个$value的地址也就自然不同了.

foreach($data as $key => &$value ){
    $statement->bindParam($key, $value);
}

4. 改用bindValue

bindParams功能差不多的方法, 还有一个bindValue. 此方法接收的是值变量, 并不接收地址.

想来对于我们这种功能情况, 官方的想法本来就是用bindValue方法吧, bindParams方法暂时没想到什么使用场景.

5.直接将参数传给execute

execute也可以接收参数的绑定. 故, 我们也可以将参数的绑定直接传给它, 中间不用调bind方法了.

$ret = $statement->execute($data);

最后, bindParam方法, 明显是希望 sql已经创建之后, 其中的值会延后获取. 不过我想了想没有想到具体的应用场景.

在最后, 对于这种参数中接了引用的方法, 在foreach中调用都要小心一些.

标签:username,key,绑定,value,PDO,foreach,statement,PHP,data
来源: https://www.cnblogs.com/hujingnb/p/15362058.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有