У меня есть код, который должен отображать сообщения между пользователями. По какой-то причине данные не совпадают, и я не уверен, где в моем коде ошибка. Я пытался изменить свои операторы if для $x < $sender, но это не сработало.
но отображаемые данные не совпадают с информацией базы данных.
Сообщение «Test 2» было отправлено с woof3, поэтому оно должно быть зеленым, а не синим при входе в систему как woof. И "тест снова" был отправлен из woof, поэтому он должен быть синим при входе в систему как woof
Отредактируйте рабочий код ниже, без pdo, потому что я еще не закончил этот проект, и я сохраняю его на конец, чтобы упростить тестирование.
<?php
include "../Site/db.php";
$url = $_SERVER['REQUEST_URI'];
$urlArray = explode('=', $url);
$Username = $urlArray[sizeof($urlArray) - 1];
$Myself = $_SESSION['username'];
$sql = "SELECT * FROM messages ORDER BY `Id` ASC";
$result = $conn->query($sql);
// Header of message box
echo '<div id = "messages" class = "messagePersonBox shadow">
<span class = "usersname" name = "receiver"><a href = "Account?='.$Username.'">'.$Username.'</a></span>
<hr style = "margin-top:24px">
<div id = "allMessages"class = "allMessages">
';
// $sql2 = "SELECT * FROM messages WHERE Sender = '$Myself' ORDER BY `Id` ASC";
// $result2 = $conn->query($sql2);
$sql3 = "SELECT * FROM messages
WHERE (Sender = '$Myself' AND Receiver = '$Username')
OR (Receiver = '$Myself' AND Sender = '$Username') ORDER BY `MessageTime` ASC";
$result3 = $conn->query($sql3);
print_r($result3);
$x = 0;
$sql4 = "SELECT * FROM messages WHERE Sender = '$Myself'";
$result4 = $conn->query($sql4);
$sql5 = "SELECT * FROM messages WHERE Receiver = '$Myself'";
$result5 = $conn->query($sql5);
$totalSender = mysqli_num_rows($result4);
$totalReceiver = mysqli_num_rows($result5);
// might have to add both totals for while loop
// to get total messages
$totalmessages = mysqli_num_rows($result);
// For receiving
while ($x < $totalmessages) {
// output data of each row
if ($result3->num_rows > 0) {
if ($row = $result3->fetch_assoc()) {
$Sender = $row['Sender'];
$Message = $row['Message'];
$Receiver = $row['Receiver'];
$TimeSent = $row['MessageTime'];
}
}
$class = $Sender == $Myself ? 'messageDisplay' : 'messageDisplay2';
// sending a message
echo '<div id = "messages2" class = "'.$class.'">'.$Message.'<span style = "float: right;margin-top:2px"><font size=1>'.time_elapsed_string($TimeSent).'</span></font></div>';
$x++;
}
// Typing part of message
echo '</div>
<input type = "text" id = "messagetosend" name = "message" class = "messagetype" placeholder = "Type a message..."><span id = "send" class = "messageSend">↩</span>
</div>';
?>
Я могу добавить больше информации, если это необходимо.
Почему бы не использовать JOIN вместо того, чтобы использовать так много запросов?
@Qirel, идентификатор разговора был добавлен в последнюю минуту, чтобы просто проверить это, поэтому мне не нужно было иметь два разных запроса. Два других запроса (sql4 и 5) предназначены только для подсчета отправленных и полученных сообщений. , исправит ли использование Join мою проблему с несоответствием данных?






Я предлагаю вам сделать шаг назад и немного изменить структуру этого подхода.
Например, вам не нужен conversationID (по крайней мере, не в его нынешнем формате), так как вы можете вычесть его из Sender и Receiver, что более точно. Вам также не нужен MessageDate, поскольку MessageTime — это значение даты и времени, которое содержит как дату, так и время. Итак, conversationID и MessageDate можно убрать.
Затем мы можем очистить количество запросов. Вы хотите получить все сообщения, где вы являетесь отправителем, а другой пользователь является получателем, или, где вы являетесь получателем, а другой пользователь является отправителем этого сообщения. Затем мы сортируем по дате (не по идентификатору!), И проверяем, должно ли сообщение быть зеленым или синим, в зависимости от значения Sender этой строки — устанавливаем переменную $class с одним значением для синего, если отправитель является текущим пользователем, и зеленым в противном случае. .
Обратите внимание, что при выводе блоков HTML вы можете выйти из PHP, что упрощает чтение (и работу с кавычками). У вас также были элементы HTML с тем же идентификатором, что недопустимо.
Вы также должны использовать подготовленные операторы при работе с переменными в запросе.
<?php
include "../Site/db.php";
$url = $_SERVER['REQUEST_URI'];
$urlArray = explode('=', $url);
$Username = $urlArray[sizeof($urlArray) - 1];
$Myself = $_SESSION['username'];
$sql = "SELECT Message, MessageTime, Sender, Receiver
FROM messages
WHERE (Sender = ? AND Receiver = ?)
OR (Receiver = ? AND Sender = ?)
ORDER BY `MessageTime` ASC");
if (!$stmt = $conn->prepare($sql)) {
error_log($conn->error);
die("An error occurred fetching messages");
}
$stmt->bind_param("ssss", $Myself, $Username, $Myself, $Username);
$stmt->bind_result($message, $timeSent, $sender, $received);
if (!$stmt->execute()) {
error_log($stmt->error);
die("An error occurred fetching messages");
}
?>
<!-- Header of message box -->
<div id = "messages" class = "messagePersonBox shadow">
<span class = "usersname" name = "receiver"><a href = "Account?=<?php echo $Username; ?>"><?php echo $Username; ?></a></span>
<hr style = "margin-top:24px">
<div id = "allMessages" class = "allMessages">
<?php
while ($stmt->fetch()) {
$class = $sender == $Myself ? 'messageDisplay' : 'messageDisplay1'; // Check which class should be used; if I'm the sender, show messageDisplay, if not show MessageDisplay1
?>
<div class = "<?php echo $class; ?>
<?php echo $message; ?>
<span style = "float: right; margin-top: 2px">
<?php echo time_elapsed_string($timeSent); ?>
</span>
</div>
<?php
}
?>
<!-- Typing part of message -->
</div>
<input type = "text" id = "messagetosend" name = "message" class = "messagetype" placeholder = "Type a message..."><span id = "send" class = "messageSend">↩</span>
</div>
<?php
$stmt->close();
спасибо за помощь и предоставление полезного совета о подготовленных заявлениях, я обязательно буду делать это с этого момента. Я получил сообщение об ошибке `Uncaught Error: вызов функции-члена bind_param() для логического значения в C:\Xammp\htdocs\SocialMedia\Admin\Users\message.php:17 Трассировка стека: #0 C:\Xammp\htdocs \SocialMedia\Site\Account.php(890): include() #1 {main} добавлено в C:\Xammp\htdocs\SocialMedia\Admin\Users\message.php в строке 17`, и я не уверен, что это означает, что я никогда не использовал подготовленный оператор
Это означает, что $stmt ложно, потому что запрос не выполнен. Посмотрите мой исправленный код для обнаружения этих ошибок (затем проверьте свои журналы ошибок).
при выполнении $sql = "SELECT Message, MessageTime, Sender, Receiver FROM messages WHERE (Sender = 'woof' AND Receiver = 'woof3') OR (Receiver = 'woof' AND Sender = 'woof3') ORDER BY MessageTime` ASC)"; ` оно по-прежнему получается ложным, несмотря на буквально те же значения. Я обрезал пробелы перед вводом данных в базу данных, потому что у меня была эта проблема ранее. при кодировании этого.
Как я уже сказал, проверяйте свои журналы ошибок (теперь, после добавления error_log()), они гораздо полезнее. Оставьте вопросительные знаки в запросе, и вы получите фактическое сообщение об ошибке.
Я думаю, проблема в том, что я использую этот код как отдельный файл, а затем делаю для него php include, поэтому возникает конфликт с кодом в двух файлах.
Просто проверьте журналы ошибок, и вы перестанете гадать, что не так! :D
Большое вам спасибо, хотя я не использовал большую часть вашего кода, так как он не работал, я использовал оператор sql, и вы научили меня тому, что `$ class = $Sender == $Myself? 'messageDisplay' : 'messageDisplay2';` это совершенно новое для меня, и это помогло. Я обновлю свой вопрос с окончательным кодом. Я не делал оператор PDO, потому что обычно сохраняю его на конец своих проектов. Спасибо!!!
Я бы действительно посоветовал вам получить ошибку и вместо этого использовать подход, предложенный в моем ответе. В настоящее время у вас есть много запросов в цикле, что очень плохо с точки зрения производительности, и вы не предотвращаете внедрение SQL. PDO — это библиотека, подобная mysqli, а не подготовленный оператор (который вы должны использовать!).
Ваш
conversationIDне обязательно уникален. Что, если вы встретите двух пользователей по имениwooиf3woofв чате? Это может дать им тот же идентификатор разговора, что иwoofиwoof3. Также выполнение$Username$Myselfбудет инвертировано, когда другая часть войдет в систему.