我封装DB(数据库)类的时候遇到的一个问题。当时的代码是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<?php /** * $dbh是pdo实例化后的对象的句柄。 * 第二个参数格式必须与第一个参数对应 * $db->paramBindExec("select user_name, notes from message where user_name=:user_name", array(':user_name'=>'guest'), false); * * @param string $sql 预执行的SQL语句 * @param array $param SQL参数绑定 */ private function paramBindExec($sql, $param) { try { $this->statement = $this->dbh->prepare($sql); // 绑定参数 if (!empty($param)) { foreach ($param as $key => $value) { // 错误的写法 // $this->statement->bindParam($key, $value); // 正确的写法 $this->statement->bindParam($key, $param[$key]); } } // 遗留下来的$value将会被引用最后一次的值 return $this->statement->execute(); } catch (PDOException $e) { $this->error_num = $e->getCode(); $this->error_message = $e->getMessage(); return false; } } |
当时的想法是,通过读取传进来的参数数组的元素为sql
语句绑定参数,调试之后发现,只能绑定最后一个参数成功,经过几番测试后。
上了官网看手册–手册的解释是:
绑定一个PHP变量到用作预处理的SQL语句中的对应命名占位符或问号占位符。 不同于
PDOStatement::bindValue()
,此 变量作为引用被绑定,并只在PDOStatement::execute()
被调用的时候才取其值
看到引用二字方醒悟,并不是循环一次,绑定一次参数。而是循环所有次数,才将参数绑定上去。而我绑定的变量每一次都是$value
。
最后将$value
改成$param[$key]
即可