0

我正在开发一个简单的网络聊天服务器。我有两个表:
chatMsgs:

  • 行 ID
  • 用户名
  • 时间
  • 行动
  • 目标
  • 信息

在线用户:

  • 用户名
  • 行动
  • 最后登录

我将如何从 online.LastActive < %t%-120 的 onlineUsers 中删除任何行以及从 onlineUsers 中删除的任何项目,我想在 chatMsgs 中添加一个新行

Username=onlineUsers.username,
LastAction='logout',
Time=%t%,
Message='Timed out after 2min'

%t% 只是一个占位符,将替换为 php 的 time() 返回值。如果可能的话,我想通过一次调用 mysqli_query 处理程序来做到这一点,尽管查询字符串可以包含 mysql 服务器的多个指令

以下作品afaik(尚未彻底测试),但我想知道是否有更好的方法:

<?php
    // $db is an mysqli database link.

    $t = time()
    $e = $t - 120,
    $q = "SELECT Username FROM onlineUsers WHERE LastActive<={$e};",
    $r = $db->query($q);

    if (!$r)
        die('db error');

    elseif ($r->num_rows > 0) {
        $q = '';

        $r = $r->fetch_all(MYSQLI_NUM);
        for ($n in $r)
            $q .= "INSERT INTO chatMsg(Username,Time,Action,Message) VALUES('{$n}',{$t},'Logout','Timed out after 2min');";

        $q .= "DELETE FROM onlineUsers WHERE LastActive<={$e};";

        $r = $db->query($q);
        if (!$r) 
            die('db error');
    }
?>
4

2 回答 2

1

如果您想在单个 SQL 语句中完成所有这些操作,那么以下内容就足够了(使用上面的 $t 和 $e 变量):

INSERT INTO chatMsg(Username, Time, Action, Message)
SELECT Username, {$t}, 'logout', 'Timed out after 2 mins'
FROM onlineUsers
WHERE LastActive <= {$e};

DELETE FROM onlineUsers WHERE LastActive <= {$e};

请注意,可能会发生竞争条件 - 如果用户在 INSERT 和 DELETE 语句之间执行某些活动,它们仍将从 onlineUsers 表中删除。您可以绕过此加载所有“要删除”的条目,首先调用删除,然后添加注销消息,但这与您的原始要求相反。

于 2012-06-09T18:45:16.750 回答
0

SQL 查询:

INSERT INTO chatMsgs
VALUES ($username, $time, "logout", $target, $message);

DELETE FROM onlineUsers
WHERE Username = $username;
于 2012-06-09T09:47:56.847 回答