【问题标题】:Invalid parameter number: no parameters were bound参数号无效:未绑定任何参数
【发布时间】:2015-07-29 01:15:16
【问题描述】:

我有一个使用 php 和 mysql 的静态聊天应用程序,这是在聊天框中显示消息的代码

$sql="SELECT id,msg,time,msg.from,msg.to from msg WHERE (msg.from='".$_SESSION["username"]."' OR msg.from='".$_SESSION["tousermessage"]."') AND (msg.to='".$_SESSION["tousermessage"]."' OR msg.to='".$_SESSION["username"]."') ORDER BY time";
$ex=$conn->prepare($sql);
$ex->execute();

echo "<div class='text-wrap'>";
while($result=$ex->fetch(PDO::FETCH_ASSOC))
{
    if ($result['from']==$_SESSION["username"])
    {
        echo "<div class='message-view' >"; 
        echo "<b class='name'>".$_SESSION["username"]."</b></br>";
        echo "<p class='subject'>".$result["msg"]."</p><p class='time'>".$result["time"]."</p>";
        echo "</div>";
    }
    else
    {
        echo "<div class='message-view' style='background-color: rgb(216, 236, 244);'>";    
        echo "<b class='name'>".$_SESSION["tousermessage"]."</b><br>";
        echo "<p class='subject'>".$result["msg"]."</p><p class='time'>".$result["time"]."</p>";
        echo "</div>";
    }
    if($result['to']==$_SESSION['username'])
    {
        $sqlupdate="UPDATE msg SET readmsg=1 WHERE id=".$result['id']." and msg='".$result["msg"]."'";      
        $ex1=$conn->prepare($sqlupdate);
        $ex1->execute();
    }
}
echo "</div>";

有时会显示异常:

SQLSTATE[HY093]:参数号无效:未绑定任何参数。

消息被插入到 msg 表中,但在显示消息期间发生错误。错误随机发生在发送方或接收方或双方。我找不到模式或它发生的原因!

【问题讨论】:

  • 您提到插入后会发生这种情况,但您发布的代码不包含任何INSERT 语句...
  • 对不起!更正了!
  • 您应该添加诊断输出以显示导致失败的命令。但是请注意,您有一个更大的问题 - 您的代码容易受到 SQL 注入的影响。你应该改用prepared statements

标签: php mysql pdo


【解决方案1】:

根据准备好的语句范例,您没有使用 bind_param。

在您的选择中:

$sql = "SELECT id,msg,time,msg.from,msg.to 
        FROM msg 
        WHERE msg.from IN (?, ?) 
            AND msg.to IN (?, ?)
        ORDER BY time";

$ex = $conn->prepare($sql);
$ex->bind_param("s", $_SESSION["username"]);
$ex->bind_param("s", $_SESSION["tousermessage"]);
$ex->bind_param("s", $_SESSION["username"]);
$ex->bind_param("s", $_SESSION["tousermessage"]);
$ex->execute();

在你的更新中:

$sql = "UPDATE msg 
        SET readmsg=1 
        WHERE id = ? 
            AND msg = ?";

$ex1 = $conn->prepare($sql);
$ex1->bind_param("i", $result['id']);
$ex1->bind_param("s", $result["msg"]);
$ex1->execute();

上面允许您准备好的语句接受参数化字符串格式的参数(使用“?”表示参数),并通过 bind_param() 方法接受带有类型信息的参数。

这允许数据库引擎在执行查询之前正确地转换和转义参数。

如果您没有绑定参数,那么使用准备好的语句是没有意义的,这可能就是您收到该警告的原因。

附带说明,查询的串联(如您在上面所做的)是一个非常糟糕的习惯 - 它会让您打开 SQL Injection


有关准备好的语句的更多信息,请参阅文档:

http://php.net/manual/en/mysqli-stmt.prepare.php

【讨论】:

  • 但是警告不应该在显示第一条消息之前出现吗?为什么它似乎出现在随机消息之后?
  • 上面的代码根本就不是写msg.msg。我怀疑您在INSERT 声明中遇到了类似的问题(您没有在此处发布)。将所有准备好的语句切换到上述范例,你应该已经准备好了。
猜你喜欢
  • 1970-01-01
  • 2017-01-31
  • 1970-01-01
  • 2016-03-13
  • 1970-01-01
  • 1970-01-01
  • 2016-02-05
  • 2012-06-13
相关资源
最近更新 更多