仅使用最后一个参数的MySQL PDO名称 - 值准备语句

时间:2015-02-23 19:32:09

标签: php pdo mysqli

正如标题所述,我正在使用带有预准备语句的MySQL PDO,并且在执行时,我将一个值(最后提供的值)推送到所有字段。

表格如下:

  • id(int - auto-increment)
  • a_id(int)
  • b_id(int)

INSERT看起来像这样:

INSERT INTO my_table(a_id, b_id) 
VALUES (:a_id, :b_id)

要插入的代码看起来像这样......

$stmt = $conn->prepare($sql);

foreach($params as $k => $v) {
    $stmt->bindParam(
        $k,
        $v
    );
}

$stmt->execute();

语句成功插入一个值(确认$ conn存在,活动和打开,语句设置和参数绑定)。

我已经通过 foreach 中的调试确认了这些值,其中我得到了两个参数(在$ params中)":a_id" => 1,":b_id" => 9999 ...

我的记录虽然是({new_id},9999,9999)。*

这意味着它会看到并使用":b_id" => 9999,但似乎丢弃或覆盖":a_id" => 1 ...

我想也许下划线是一个问题(但显然有几个人过去已经审查了来源,表明下划线很好......虽然连字符不是)。

我没有重复使用参数(我的理解是每个准备好的声明允许使用一次)...

是否有一些命名参数问题我在这里丢失了?由于它基本上是 - > bindParam()到 - > execute(),因此我没有足够的空间进行故障排除。

我尝试使用无脂肪框架解决基于ORM的数据访问速度问题,但我不能认为那里有干扰。

作为参考,这是在PHP 5.5.8 / Windows / IIS下运行。

修改:*

我可以确认,移动到位置参数是做同样的事情。

INSERT INTO my_table(a_id, b_id) 
VALUES (?, ?)

代码已更改为...

$stmt = $conn->prepare($sql);

$i = 1;
foreach($params as $value) {
    $stmt->bindParam(
        $i,
        $value
    );
    $i++;
}

$stmt->execute();

澄清如何设置$ params数组......事情正在传递给这段代码(这是抽象数据库处理程序的核心),并且数组是手动构建的......

$results = \XX\DB::do_cmd(
    $db, 
    self::SQL_INSERT, 
    array(
        ':a_id' => intval($this->a_id),
        ':b_id' => intval($this->b_id),
    )
);

仍然得到({new_id},9999,9999)......

注意:为了消除混淆,除了进行基于位置的传递,我还硬编码值以查看我得到的内容......

$results = \XX\DB::do_cmd(
    $db, 
    self::SQL_INSERT, 
    array(
        1,
        1234,
    )
);

我的记录出来了({new_id},1234,1234)。同样的问题,不同的价值观。

我感觉那里有一个"陷阱"这里......但我不知道它是什么。

有趣的是,我在INSERT之前根据这两个值(为了防止重复)仔细检查表中的现有记录,并且检查正确地识别出记录在那里......尽管它在错误中数据库...这意味着SELECT和INSERT使用参数执行相同的操作(尽管并非所有令人惊讶的,因为参数处理是相同的)。

EDIT2:

更新以注意已解决。使用...

$stmt->execute($params); // scrap the foreach nonsense...

bindValue()而不是bindParam()也是合适的。

注意:我使用的是以下PHP文档(http://php.net/manual/en/pdo.prepared-statements.php),它没有区分bindValue()和bindParam()......

2 个答案:

答案 0 :(得分:2)

感谢所有人的帮助!

我选择了Michael的解决方案,但也对Ryan进行了测试。

更新以注意已解决。使用...

$stmt->execute($params); // scrap the foreach nonsense...

bindValue()而不是bindParam()也是合适的。

根据Ryan的评论,总结一下,我推出答案。

再次感谢!

答案 1 :(得分:0)

变量必须是引用调用:

$stmt = $conn->prepare($sql);

foreach($params as $k => &$v) {
    $stmt->bindParam(
        $k,
        $v
    );
}
$stmt->execute();

请在此处查看第一个用户提供的评论:

http://php.net/manual/en/pdostatement.bindparam.php