如何解决在获取的数据中添加额外的变量
如下所示,我正在获取idsOfSenders
,并且正在执行另一个查询以获取该用户的信息。到目前为止,一切正常。
但是正如您所看到的,我还有另一个变量$msgDate
,我想将其放在每个用户的输出中。我该怎么办?
$recieverId = 33;
$query = "SELECT from_msg,chat_date FROM msg WHERE `to_msg` = '$recieverId' ORDER BY `chat_date` DESC";
$res = mysqli_query($conn,$query);
while($row = mysqli_fetch_array($res)) {
$idsOfSenders[] = $row['from_msg'];
$msgDate[] = $row['chat_date'];
}
$queryb = "SELECT fullname,username FROM `users` WHERE `id` IN('".implode("','",$idsOfSenders)."')";
$resb = mysqli_query($conn,$queryb);
if($resb->num_rows >0){
$json=[];
while(($rowb = $resb->fetch_assoc())) {
$json[] = $rowb;
}
echo json_encode($json);
} else {
echo "0";
}
case 'gmmn':
//ini_set('display_errors',1);
//ini_set('display_startup_errors',1);
//error_reporting(E_ALL);
if(isTheseParametersAvailable(array('i'))){
if (!$conn) {
return;
}
//$recieverId = str_replace(" ","",$_POST["i"]);
$recieverId = 33;
$sqlCheckMsg = "SELECT from_msg,chat_date,fullname,username FROM msgNew LEFT JOIN users_table on users_table.id = msgNew.from_msg WHERE to_msg = ? ORDER BY `chat_date` DESC";
$stmt = $conn->prepare($sqlCheckMsg );
$stmt->bind_param("i",$recieverId);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($from_msg,$chat_date,$fullname,$username);
if($stmt->num_rows > 0){
$rows=[];
while($stmt->fetch()) {
$rows[] = array('from_msg'=>$from_msg,'chat_date'=>$chat_date,'fullname'=>$fullname,'username'=>$username);
}
} else {
echo "0";
return;
}
echo json_encode($rows);
}
break;
解决方法
这是JOIN
派上用场的地方。您可以一次完成两个查询的操作,此外,无需进行可怕的implode
注入:
SELECT from_msg,chat_date,fullname,username
FROM msg
LEFT JOIN users on users.id=msg.from_msg
WHERE to_msg=? ORDER BY `chat_date` DESC
这应该显着更快,更安全,因为在返回数据库之前,它不涉及通过PHP的往返。
,注意:确保
检查查询性能msg
上的索引from_msg
使该JOIN
操作有效。您可以使用EXPLAIN SELECT ...
毫无疑问,您应该使用@tadman的答案。话虽如此,您遇到的主要问题是单个用户可以向接收者发送任意数量的消息。
假设我usera
,并且一周前,昨天和今天我已将消息发送到receiverId 33
。有3条带有3个不同日期的消息。您需要为该用户创建3行,以反映3条消息。
我不建议您使用以下方法,但是它可以解决用户可以发送多个msg以及关联的chat_date的事实,从而可以根据您的查看方式工作。这段代码会将消息存储在一个数组中,并将它们添加到每个用户的获取结果中。您仍然需要处理'chat_date'是一个日期数组而不是像其他结果集一样的单个标量值这一事实。
$recieverId = 33;
$query = "SELECT from_msg,chat_date FROM msg WHERE `to_msg` = '$recieverId' ORDER BY `chat_date` DESC";
$res = mysqli_query($conn,$query);
while($row = mysqli_fetch_array($res)) {
$idsOfSenders[] = $row['from_msg'];
//msgDate will be an array of all the dates sent for this member to the other member
$msgDate[$row['from_msg']][] = $row['chat_date'];
}
$queryb = "SELECT id,username FROM `users` WHERE `id` IN('".implode("','",$idsOfSenders)."')";
$resb = mysqli_query($conn,$queryb);
if($resb->num_rows >0){
$json=[];
while(($rowb = $resb->fetch_assoc())) {
// Add the array of this user's sent message dates
$rowb['msg_date'] = $msgDate[$rowb['id']];
// get rid of the users.id column if you don't want it
unset($rowb['id']);
$json[] = $rowb;
}
echo json_encode($json);
} else {
echo "0";
}
这确实假定用户的表主键名为id。如果没有,则需要更改相关代码以反映存储在msg表的from_msg和to_msg中的用户表主键的名称。
您应该可以看到,这是一个丑陋的骇客。关系数据库将为您解决这一问题。再说一次,@ tadman的解决方案是解决之道,但我认为,如果我向您展示了如何使其工作以及丢失的东西,它可能会帮助您更好地了解当前的问题。
更新:既然您实现了@tadman的查询,我个人不会绑定结果,因为这导致您在这种情况下使用许多您真正不在意的变量。这比较简单:
$sqlCheckMsg = "SELECT from_msg,username FROM msgNew LEFT JOIN users_table on users_table.id = msgNew.from_msg WHERE to_msg = ? ORDER BY `chat_date` DESC";
$stmt = $conn->prepare($sqlCheckMsg );
$stmt->bind_param("i",$recieverId);
$stmt->execute();
$result = $stmt->get_result();
$rows = array();
while ($row = $result->fetch_assoc()) {
$rows[] = $row;
}
if (count($rows) > 0) {
echo json_encode($rows);
return;
} else {
echo "0";
return;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。