将数组绑定到预准备语句的正确方法?

时间:2013-05-16 19:56:41

标签: php mysql mysqli

这可能已经被问了几次,但是我很难理解如何将数组绑定到mysqli预处理语句。

我要做的是在消息线程中查询用户ID列表,然后插入到消息表中,以便可以通知用户新消息回复。

这是我尝试过的:

//now check which users are in the message thread
$stmt2 = $mysqli->prepare("SELECT DISTINCT user_id_2
FROM uc_user_messages
WHERE thread_id =  ?");
$stmt2->bind_param("i", $this->thread_id_clean);
$stmt2->bind_result($user_2_id);
$stmt2->execute();

$stmt3 = $mysqli->prepare("
INSERT INTO `users`.`uc_user_messages`(
    `id` ,
    `message_id` ,
    `user_id_2` ,
    `read` ,
    `thread_id`
    )
    VALUES (
    NULL , ?, ?, ?, ?
    );
");

//now insert the message into the user_messages table so the user can be notified of a new message
while ($row = $stmt2->fetch()){
    $stmt3->bind_param("iiii", $inserted_id, $user_2_id, $read, $this->thread_id_clean );
    $stmt3->execute();
}   

我做错了什么?我已经尝试将准备好的语句放在循环中,但我继续收到此错误:

  

致命错误:在非对象

上调用成员函数bind_param()

我还使用测试数据手动运行查询,因此我知道这是导致值无法正确绑定的循环。

编辑:我应该补充说,select查询工作正常,而且是导致错误的插入查询。

3 个答案:

答案 0 :(得分:0)

一旦var绑定到prep语句,它就会保持绑定。

这意味着只调用bind_param一次(在循环之外),然后只重复两步循环"更改var值/执行"。

php.net: Check section #3 INSERT prepared once, executed multiple times

还要确保您用于数据库和表名的引号不会干扰PHP backtick operator.(在这种特定情况下,您可以省略这些引号。)

答案 1 :(得分:0)

  

致命错误:在非对象

上调用成员函数bind_param()

这意味着$ stmt2或$ stmt3不是对象。如果解析或验证查询有任何问题,prepare()函数将返回false。但false->bind_param()无法发挥作用。

这是许多MySQL开发人员常犯的错误。解决方案是您必须检查prepare()是否返回成功而不是false

示例:

$stmt2 = $mysqli->prepare("...");
if ($stmt2 === false) {
  // do something to report $mysqli->error, and return
}

另见http://php.net/manual/en/mysqli.error.php

答案 2 :(得分:0)

  1. 您没有检查错误。按照这里解释的方式进行:https://stackoverflow.com/a/15447204/285587
  2. 错误很可能是“命令不同步”之类的错误。您必须在第一个查询中使用store_result()来避免这种情况。奇怪的是,比尔有一个perfect answer which is first on google search - 你可以参考它来了解详情。
  3. 我只能得到你正在谈论的阵列。