我有一个使用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表中,但在显示消息期间发生错误。错误在发送方或接收方或两侧随机发生。我找不到一种模式或它发生的原因!
答案 0 :(得分: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()方法接受带类型信息的参数。
这允许数据库引擎在执行查询之前正确地转换和转义params。
如果你没有约束params,那么使用预备语句是没有意义的,这可能就是你得到警告的原因。
在旁注中,查询的连接(正如您上面所做的那样)是一个非常糟糕的习惯 - 它可以让您打开SQL Injection
有关预准备陈述的更多信息,请参阅文档: