PDO Insert 将值 1 写入具有绑定参数的所有字段
Posted
技术标签:
【中文标题】PDO Insert 将值 1 写入具有绑定参数的所有字段【英文标题】:PDO Insert writes value of 1 into all fields with bound parameters 【发布时间】:2014-05-31 15:58:34 【问题描述】:我有一个包含以下字段/数据类型的联系人表:contactid
(PK,自动递增,不为空)、fname varchar(50)
、lname varchar(50)
、email varchar(50)
、is_member tinyint(1)
(即布尔值) 和createdate date
。
数据被提交到表单所在的同一个php页面,$_POST
数组的值被打包成一个Contact对象并传递给如下函数:
<?php
public static function insertContact(Model $model, Contact $contact)
$database = new Database();
$sql = 'INSERT INTO contact (fname, lname, email, is_member, createdate) VALUES (:fname, :lname, :email, :is_member, CURDATE())';
$params = array(
':fname' => $contact->getFirstname(),
':lname' => $contact->getLastname(),
':email' => $contact->getEmail(),
':is_member' => intval($contact->isMember())
);
$result = $database->query($sql, $params, 'LASTID'); // Will return last inserted ID.
$model->notify('Added contact ID ' . strval($result) . ' to the database.');
?>
如果另一个检查联系人是否已存在的函数返回false
,则调用此函数。我正在使用 PDO 准备好的语句,对于 SELECT
语句来说一切正常,但是当我尝试执行这个 INSERT
语句时,我遇到了问题。 $params
数组是正确的,并且参数的数量与占位符的数量相匹配,但是 is_member
字段会导致问题。如果值为1
,则INSERT
完成,但结果行如下所示:
以前有人见过这种行为吗?此外,如果is_member
的值为0
,则查询将完全失败,并出现PDOStatement 警告[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
。我没有得到的是 $params
具有正确数量的值来绑定到占位符标记。
[更新:]$database->query()
方法如下:
<?php
// Return type is the format in which to return the result of the query.
public function query($sql, $params, $returnType)
if($stmt = $this->connection->prepare($sql))
foreach($params as $key => $value)
if($value != 'noParams')
$stmt->bindParam($key, $value);
if($stmt->execute()) // execute() returns TRUE on success
switch($returnType)
case 'ASSOC':
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
break;
case 'LASTID':
$result = $this->connection->lastInsertId();
break;
// ... more cases, etc.
else
$result = null;
die('Error: ' . $this->connection->error);
return $result;
else
die('Prepare failed: (' . $this->connection->error . ')');
?>
如前所述,此query()
方法适用于为SELECT
操作准备的语句,但是当尝试执行简单的INSERT
时,它会表现出上述行为。任何帮助表示赞赏!谢谢!
【问题讨论】:
以前没有人见过这种行为。 我更想问$database->query()函数是做什么的。 显示$database->query()
方法的代码
@MarkBaker,我已更新帖子以包含$database->query()
的代码。我了解到这是用于 PDO 准备语句的一种相当常见的方法,并且使用命名占位符比使用位置 ?
标记更直接。
【参考方案1】:
第一个问题:
if($value != 'noParams')
如果值为 0,那么这将是一个错误匹配,因为它是一个 松散类型 比较;所以“假”类型值(null
、0.0
、false
等)会给你带来问题,因为它不会绑定数组中的任何假值......这解释了你的 Invalid parameter number: number of bound variables does not match number of tokens
错误。 ..
严格比较:
if($value !== 'noParams')
你的第二个问题:
引用PHP Docs
与 PDOStatement::bindValue() 不同,该变量被绑定为引用,并且只会在调用 PDOStatement::execute() 时进行评估。
在您实际执行语句时,$value
仅具有来自绑定循环的最后一次迭代的值,即来自is_member
数组元素的值,即1
。这就是为什么您的所有绑定变量除了 1
值之外什么都没有得到
将您的 foreach
循环更改为
foreach($params as $key => &$value)
所以$value
是“通过引用”,它应该是绑定到每个绑定变量的正确引用
或者,使用bindValue()
而不是bindParam()
整体:
所以为了彻底修复
foreach($params as $key => &$value)
if($value !== 'noParams')
$stmt->bindParam($key, $value);
【讨论】:
啊,是的,效果很好!不敢相信我错过了它没有绑定参考。非常感谢!【参考方案2】:您是否尝试过使用 exec 与查询?
在文档中: http://us1.php.net/manual/en/pdo.exec.php
对比 http://us1.php.net/pdo.query
底线:PDO::query — 执行 SQL 语句,将结果集作为 PDOStatement 对象返回 while PDO::exec — 执行一条 SQL 语句并返回受影响的行数
【讨论】:
以上是关于PDO Insert 将值 1 写入具有绑定参数的所有字段的主要内容,如果未能解决你的问题,请参考以下文章
Pdo - 将值插入数据库错误 SQLSTATE [HY093] [重复]
在 PDO 中的执行函数中将 NULL 值绑定到具有关联数组的命名占位符的问题