【问题标题】:Displaying message status: read and unread (differs from other users) in PHP/MySQL messaging system在 PHP/MySQL 消息系统中显示消息状态:已读和未读(与其他用户不同)
【发布时间】:2016-10-27 17:30:45
【问题描述】:

我正在显示与每个用户不同的消息状态。假设user1user2 发送消息,user1 的消息状态然后设置为read,而user2 的消息默认设置为unreaduser2点击消息后会更新。

所以在这种情况下,user1(来自收件箱)的消息将具有灰色字体,表示该消息设置为read(因为发送者是user1)。另一方面,user2 有一个粗体字,表示邮件是unread

这是表的第一个结构:

message(messageid, fromid, toid, message, timestamp, status)

这里的问题是,如果我将消息状态更新为read,它会影响另一端(user2)。所以我添加了另一列,它将设置不同于user1user2 的状态:

message(messageid, fromid, toid, message, timestamp, from_status, to_status)

这里,from_status 用于fromidto_status 用于toid。但是我在如何使用这些值来显示状态时遇到了问题。

我在第一次尝试时使用的 PHP 代码如下:

<?php 
$id = $_SESSION['id'];
$query = mysql_query("SELECT m.* FROM message m
                                  LEFT JOIN message m2 ON (
                                  (m.fromid=m2.fromid AND m.toid=m2.toid) OR
                                  (m.fromid=m2.toid AND m.toid=m2.fromid)
                                  ) AND m.timestamp<m2.timestamp
                                  WHERE (m.fromid='$id' OR m.toid='$id') AND m2.toid IS NULL ORDER BY timestamp DESC");

while ($message = mysql_fetch_array($query)) {
  if ($message['status'] === 'unread') {
    // bold font style will be applied
  }
  else {
    // gray-colored font will be applied
  }
}
?>

(查询从每个用户获取最新对话的每个对话。)

这些代码对主要用户 user1 工作正常,但会影响另一方,它认为从 user2 收到的消息设置为 readunread

所以,我在修改后的表上遇到了一些麻烦,每个用户都有 2 个单独的 status。我怎样才能完成这些工作?

【问题讨论】:

  • 是否有将状态重新设置为未读的选项?因为否则,您可以假设,如果查看邮件的人是发件人,则该邮件将被阅读,并且有一个状态字段来跟踪收件人是否已阅读。
  • 为了获得更好的解决方案,请将字段重命名为 sender_statusrecipient_status,以便清楚哪个是哪个,并根据现在正在阅读消息的人更新适当的字段跨度>
  • 要获得更优雅的解决方案,请修改数据库,以便为消息收件人创建一个新表,其中包含“usedID”、“status”和“role”等字段,其中角色为“发件人”或收件人'。这样您就可以将同一条消息发送给多个人,并单独跟踪他们的每个状态。
  • @andrewsi 这会重置user2 的状态吗?
  • 您好。 @GhostGambler 出于充分的理由删除了 [已解决] 标题标签,我们在这里不这样做。我还把附加的答案移到了维基风格的答案中——如果您想添加自己的答案,请在以后使用答案框。此外,如果高级用户编辑了您的帖子,请在恢复他们的编辑之前与他们联系 - 他们可能了解您不了解的样式和格式。我还从您的代码块中删除了“sn-p”功能,因为 SQL/PHP 不会在浏览器中运行。

标签: php mysql messaging


【解决方案1】:

(代表 OP 发布。)

感谢@Rafal Mnich,我已经设法解决了这个问题。所以我抓取了他查询的一部分并进行了一些修改,它就可以了。

这是查询:

SELECT m.msgid, m.fromid, m.toid, m.content,
  CASE
    WHEN m.fromid = '$id' THEN m.frommsgstatus
    WHEN m.toid = '$id' THEN m.tomsgstatus
  END AS msgstatus
FROM msg m
  LEFT JOIN msg m2
    ON ((m.fromid=m2.fromid AND m.toid=m2.toid) OR (m.fromid=m2.toid AND m.toid=m2.fromid)) AND m.timestamp<m2.timestamp
WHERE (m.fromid='$id' OR m.toid='$id') AND m2.toid IS NULL
ORDER BY m.timestamp DESC

这些显示按发件人fromid 分组的消息,还显示您与每个发件人的最新对话。并在用户双方显示正确的消息状态。

【讨论】:

  • 但是为什么需要这个左连接呢?
  • 嗨@RafałMnich,您需要在问题解锁后将其发布在问题下方 - 我代表 OP 发布了此内容,并从附加到问题的解决方案中获取了文本。跨度>
  • @RafałMnich:问题现已解锁,如果您愿意,可以在问题下方发布。
【解决方案2】:

@andrewsi 评论非常好,例如当你有很多接收器时。在你的情况下,它只是一个额外的字段,所以在我看来,只使用一个表并不是溢出。 关于您的情况,您可以在一个简单的 sql 中执行此操作:

SELECT m.*,
    CASE 
        WHEN m.fromid = $id THEN m.from_status 
        WHEN m.toid = $id THEN m.to_status
    END as read_status
FROM message m
WHERE
    m.fromid = $id OR m.toid = $id
ORDER BY timestamp DESC;

在您看来,您只是在检查 read_status 字段

【讨论】:

  • 我现在有点理解这些了。我测试了查询并给了我消息状态。我所需要的只是实现它。谢谢。
  • 我会先实现它,一旦我让它工作我会标记它。你有我的话。您介意将我的问题投票给其他可能遇到与我相同问题的程序员吗?这将是一个很大的帮助。 :)
  • 我还有一个问题。这些部分只解决了我的问题的一部分。我的收件箱由发件人 from 分组,该发件人是从上面的查询中对我的 php 代码给出的。我该如何修改这些?它还应该显示最新的对话。
  • 哦,别介意。我设法使用您的部分代码解决了它。你有我的感谢伙伴。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
  • 2015-06-07
  • 2022-11-04
  • 2015-11-05
  • 2021-09-05
  • 1970-01-01
相关资源
最近更新 更多