You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何每秒从MySQL数据库拉取数据实现聊天应用消息自动更新

聊天应用自动拉取新消息实现方案

实现自动更新有两种常用方案,这里优先提供改造成本最低的短轮询方案,适合流量不大的个人项目使用:

1. 拆分独立后端查询接口

把消息/聊天列表的查询逻辑抽成单独的PHP文件,避免每次更新都要加载整个页面的内容,这里以消息查询为例,新建get_messages.php,代码如下:

<?php
// 复用你原项目的数据库连接配置即可
$db = [你的数据库连接实例];

if (!isset($_GET['id']) || !preg_match("/^[0-9]+$/", $_GET['id'])) {
    echo json_encode(['code' => 400, 'msg' => '参数非法']);
    exit;
}
$user_id = intval($_GET['id']);
// 新增last_id参数,仅拉取上次查询之后新增的消息,减少数据传输
$last_msg_id = isset($_GET['last_id']) ? intval($_GET['last_id']) : 0;

// 改用预处理绑定参数,修复原代码的SQL注入风险
$fetch_sql = "SELECT * FROM users_messages WHERE (from_user=? OR to_user=?) AND id > ? ORDER BY id ASC";
$stmt = $db->prepare($fetch_sql);
$stmt->execute([$user_id, $user_id, $last_msg_id]);
$new_messages = $stmt->fetchAll(PDO::FETCH_ASSOC);

echo json_encode([
    'code' => 200,
    'new_last_id' => empty($new_messages) ? $last_msg_id : end($new_messages)['id'],
    'data' => $new_messages
]);
?>

如果需要自动更新#autodata里的聊天用户列表,也可以用同样的逻辑,把用户列表的查询抽成独立接口即可。

2. 前端新增定时拉取逻辑

在你的聊天页面底部加入如下JS代码,定时拉取新数据更新页面:

// 记录上次拉取的最大消息ID
let lastMsgId = 0;
// 取当前聊天用户ID
const currentChatId = new URLSearchParams(window.location.search).get('id');
// 当前登录用户ID,替换为你项目里的登录用户ID变量
const loginUserId = <?php echo $user_id; ?>;
// 消息列表容器,替换为你实际的消息列表DOM ID
const msgContainer = document.querySelector('#message-list');

function loadNewMsg() {
    if (!currentChatId) return;
    fetch(`get_messages.php?id=${currentChatId}&last_id=${lastMsgId}`)
        .then(res => res.json())
        .then(res => {
            if (res.code !== 200 || res.data.length === 0) return;
            // 更新最新消息ID
            lastMsgId = res.new_last_id;
            // 渲染新消息到页面
            res.data.forEach(item => {
                const msgDom = document.createElement('div');
                // 根据消息发送方添加不同样式
                msgDom.className = item.from_user == loginUserId ? 'my-message' : 'other-message';
                // 替换为你数据库中存储消息内容的字段名
                msgDom.innerText = item.content;
                msgContainer.appendChild(msgDom);
            });
            // 自动滚动到消息列表底部
            msgContainer.scrollTop = msgContainer.scrollHeight;
        })
}

// 页面加载先拉一次历史消息
loadNewMsg();
// 每3秒拉一次新消息,可根据需求调整间隔时长
setInterval(loadNewMsg, 3000);

优化建议

  • 原代码直接将用户输入的参数拼接进SQL语句,存在严重的SQL注入风险,所有数据库查询操作都建议改成预处理绑定参数的写法
  • 若后续项目用户量上涨,可改用WebSocket方案实现服务端主动推送,性能远高于轮询,可使用Workerman、Swoole等PHP扩展快速实现
  • 可新增未读消息计数逻辑,用户未打开对应聊天窗口时提示未读消息数量

内容的提问来源于stack exchange,提问作者Abderrahmane Bourri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 09:54:02