如何每秒从MYSQL数据库中获取数据



我正在尝试制作一个聊天应用使用HTML, CSS, JS, PHP和Mysql.
我已经完成了所有的功能,包括发送消息,接收消息,显示用户…但我面临的问题是,我需要刷新页面,每次我收到一个新的消息

我正在寻找一种方法来自动更新数据与新数据从mysql数据库。
代码:

<?php    
if ($_GET['id']){
$id = $_GET['id'];
$id = preg_replace("/[^0-9]/", "", $id);
$fetching_messages = "SELECT * FROM users_messages WHERE from_user='$id' OR to_user='$id' ORDER BY id";
$check_fetching_messages = $db->prepare($fetching_messages);
$check_fetching_messages->execute();
$messages_all = $check_fetching_messages->fetchAll();

} else {
}
?>
<div id="autodata">
<?php foreach($to_users as $to_user) : ?>
<?php
$to_user_id = $to_user['to_user'];
$to_user_name = "SELECT * FROM users_accounts WHERE id='$to_user_id'";
$check_to_user_name = $db->query($to_user_name);
while ($row_to_user_name = $check_to_user_name->fetch()) {
$id_user = $row_to_user_name['id'];
$username = $row_to_user_name['username'];
$pdp = $row_to_user_name['profile_image'];
}
if ($id_user == $user_id){
} else {
echo '
<form style="height: fit-content;" name="goto'.$to_user_id.'" action="inbox.php">
<div onclick="window.location.replace('."'".'?id='.$to_user_id."'".')" class="inbox_chat_field_user">';
if (empty($pdp)){
echo "<img class='inbox_chat_field_user_img' src='uploadsprofiledefault.jpg'/>";
} else {
echo "<img class='inbox_chat_field_user_img' src='".$pdp."'/>";
}
echo '
<span class="inbox_chat_field_user_p">'.$username.'</span>
</div>
</form>
<hr class="inbox_separing_hr">';
}
?>
<?php endforeach;?>
</div>

你不能这么做,PHP是一种服务器端语言,你不能告诉客户端从PHP刷新。

你应该考虑在浏览器中使用JavaScript。

最简单的方法是向服务器发送一个AJAX请求,每隔5秒或10秒检查一次是否有新消息,然后对响应中的消息做您想做的事情。

如果你在你的应用程序中使用jquery,你可以用这种方式发送ajax请求:

$.get( "messages.php", function( data ) {
console.log( "Data Loaded: " + data );
});

和在messages.php脚本中,您可以从数据库中获取新消息并以HTML或JSON格式返回它们

您也可以使用firebase提供的FCM服务直接将您的消息推送到客户端,查看此包用于PHP FCM。

还有其他解决方案,如websockets等…

如果您将业务逻辑与表示分离,那么直接更新代码对我来说会更容易,因此我不打算尝试这样做。相反,我将描述一种您可以使用的技术,并让您自己找出使用它的最佳方法。您可以考虑使用服务器发送的事件。参见JavaScript类EventSource。

以下"业务逻辑"PHP程序sse_cgi.php周期性地每2秒产生一个新的输出(总共5次)。在本例中,输出只是当前日期和时间的字符串形式。但它也可以是,例如,一个JSON记录。注意它输出的特殊报头:

<?php
header("Content-Type: text/event-stream");
$firstTime = True;
for ($i = 0; $i < 5; $i++) {
if (connection_aborted()) {
break;
}
$curDate = date(DATE_ISO8601);
echo 'data: This is a message at time ' . $curDate, "nn";
// flush the output buffer and send echoed messages to the browser
while (ob_get_level() > 0) {
ob_end_flush();
}
flush();
if ($i < 4) {
sleep(2); # Sleep for 2 seconds
}
}

这是将要输出的表示HTML。在这种情况下,JavaScript代码只是用更新后的值替换旧的日期。也可以将新的<li>元素附加到现有的<ul>标签上,或将<tr>元素附加到现有的<table>标签上。

<html>
<head>
<meta charset="UTF-8">
<title>Server-sent events demo</title>
</head>
<body>
<div id='date'></div>
<script>
var evtSource = new EventSource('sse_cgi.php');
var date = document.getElementById('date');
evtSource.onmessage = function(e) {
// replace old content
date.innerHTML = e.data;
};
evtSource.onerror = function() {
// occurs when script terminates:
evtSource.close();
console.log('Done!');
};
</script>
</body>
</html>

注意,这个演示引用了"业务逻辑"。返回连续日期的脚本。

重要提示

重要的是要认识到,这种技术使到服务器的连接在持续时间内保持打开状态,直到最终发送完所有数据并且业务逻辑脚本最终终止(或者浏览器中运行的表示发出对evtSource.close()的调用以关闭连接)。因此,如果同时有很多用户,这可能是一个问题。

如果您的应用程序没有有限数量的消息要返回,那么可以通过让业务逻辑脚本在发送一条消息后立即返回来克服前面描述的问题。这将断开与浏览器的连接,如果浏览器仍然存在,将自动尝试与业务逻辑脚本重新连接(注意,此重新连接可能需要一段时间):

更新的业务逻辑

<?php
header("Content-Type: text/event-stream");
# Simulate waiting for next message:
sleep(2);
$curDate = date(DATE_ISO8601);
echo 'data: This is a message at time ' . $curDate, "nn";
// flush the output buffer and send echoed messages to the browser
while (ob_get_level() > 0) {
ob_end_flush();
}
flush();

更新报告

<html>
<head>
<meta charset="UTF-8">
<title>Server-sent events demo</title>
</head>
<body>
<div id='date'></div>
<script>
var evtSource = new EventSource('sse_cgi.php');
var date = document.getElementById('date');
evtSource.onmessage = function(e) {
// replace old content
date.innerHTML = e.data;
};
</script>
</body>
</html>

最新更新