php mysql 中的消息传递系统


Messaging system in php mysql

我在我的网站上创建了一个简单的消息传递系统,新注册用户可以在其中相互发送消息。 以下mysql语句在我的网站上效果很好,但是我的问题是 -UserAUserB发送消息时,该消息会在他的收件箱中显示给UserB,并且该消息会显示给UserA他的发件箱,现在如果由于某些原因UserB从他的收件箱中删除了该消息,则该消息将从两侧删除, 我将所有邮件存储在一个表中, 现在我想要实现的是,当邮件从收件箱中删除时,它应该仍然保留在发件箱中,非常感谢任何帮助!谢谢!

表结构如下

id   message    sentby   sentto    created

收件箱.php

$you=$_COOKIE['username'];     
$st= "SELECT* FROM mbox WHERE sentto='$you' ORDER BY ID DESC LIMIT 10";

发件箱.php

$you=$_COOKIE['username'];
$st= "SELECT*FROM mbox WHERE sentby='$you' ORDER BY ID DESC LIMIT 10";
我认为

您可以保留消息内容的当前表结构。 与其添加单独的列或删除的标志,不如为邮箱使用单独的表。

所以你当前的mbox表:

id   message    sentby   sentto    created

然后是另一张桌子user_mailboxes

id   user    mailbox    message_id

在写入消息时,您必须为user_mailboxes表中的每个用户执行三次插入,一次插入消息到消息表。

因此,您的 mbox 数据如下所示:

id   message     sentby    sentto    created 
1    Hi There    UserA     UserB     2015-01-26
2    Hello Back  UserB     UserA     2015-01-26

user_mailboxes数据如下所示:

id   user        mailbox   message_id
1    UserA       Out       1
2    UserB       In        1
3    UserB       Out       2
4    UserA       In        2

这允许您删除user_mailboxes表的各个行。 这也将允许您同时向多个用户发送邮件(每个用户的新行),并允许您根据需要添加多个邮箱(输入、输出、废纸篓、重要等)。

若要查找特定邮箱的用户的邮件,只需使用联接

SELECT * FROM user_mailboxes LEFT JOIN mbox ON mbox.id = user_mailboxes.message_id WHERE user_mailboxes.user = "$user" AND user_mailboxes.mailbox = "Out";

删除时需要清理脚本,以确保user_mailboxes表中不存在孤立消息。

只需做一件事 在现有表中添加两个新字段

  1. is_sender_deleted
  2. is_receiver_deleted

如果有人将其从发件箱中删除,则is_sender_deleted值设为 1。因此,当您在发件箱中显示数据时,您只需列出字段值为 0 is_sender_deleted的所有记录。

同样的情况是,有人从收件箱中删除它,然后将is_receiver_deleted值设为 1。因此,当在收件箱中显示数据时,您只需列出is_receiver_deleted值为 0 的所有记录。

希望此解决方案对您有所帮助。

我也解决了这个任务。我认为一张表在这种情况下没有用。所以,我建议使用 2 张表:

CREATE TABLE `message` (
  `id`       int(11) NOT NULL AUTO_INCREMENT,
  `subject`  varchar(255) NOT NULL,
  `body`     text NOT NULL,
  `date`     datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `message_user` (
  `id`           int(11) NOT NULL AUTO_INCREMENT,
  `message_id`   int(11) NOT NULL,
  `user_id`      int(11) NOT NULL,
  `interlocutor` int(11) DEFAULT NULL,
  `folder`       enum('inbox','sent') NOT NULL,
  `starmark`     tinyint(1) NOT NULL DEFAULT '0',
  `unread`       tinyint(1) NOT NULL DEFAULT '1',
  `deleted`      enum('none','trash','deleted') NOT NULL DEFAULT 'none',
  PRIMARY KEY (`id`),
  CONSTRAINT `message_user_user_fk_1` FOREIGN KEY (`message_id`)   REFERENCES `message` (`id`) ON UPDATE CASCADE,
  CONSTRAINT `message_user_user_fk_2` FOREIGN KEY (`user_id`)      REFERENCES `user`    (`id`) ON UPDATE CASCADE,
  CONSTRAINT `message_user_user_fk_3` FOREIGN KEY (`interlocutor`) REFERENCES `user`    (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我认为它可以解决您的所有问题,因为消息用户彼此分离

因此,对于一条消息,我们必须创建 3 个插入,如下所示:

public static function createMessage($subject, $body, $source, $sender_id, $receiver_id)
{
    // save DATA to message table      ($subject, $body, $source)
    // save DATA to message_user table ($message_id, $sender_id, $receiver_id, 'sent')
    // save DATA to message_user table ($message_id, $receiver_id, $sender_id, 'inbox')
}

在这种情况下,对于每个用户,我们在表 message_user 中创建单独的行。因此,当user_1删除此收件箱文件夹中的邮件时,我们会将其标记为"已删除",并且对第二个用户没有影响。

因此,获取所有用户消息,我们只能像这样运行简单的 SELECT:

SELECT *
FROM message m
    JOIN message_user mu
    ON m.id = mu.message_id
WHERE mu.deleted = 'none'
    AND mu.user_id = :user_id

您可以在 mbox 表中添加类似"状态"的列,

然后,如果用户 B 删除消息,您可以将状态更改为 1,或者用户 A 删除消息,您可以将状态更改为 2。

对于收件箱 :

$you=$_COOKIE['username'];
$st= "SELECT* FROM mbox WHERE sentto='$you' AND status <> '1' ORDER BY ID DESC LIMIT 10";

对于发件箱:

$you=$_COOKIE['username'];
$st= "SELECT* FROM mbox WHERE sentby='$you' AND status <> '2' ORDER BY ID DESC LIMIT 10";

祝你好运。

不要从数据库中删除消息,而是使用该特定消息的状态作为 SHOWtoSender、SHOWtoReciver
、SHOWtoBoth 或 SHOWtoNONE(使用数据类型 ENUM 和默认值SHOWtoBoth
)。
在表格中更改为:
ID 发送方 接收方状态 time

id   message    sentby   sentto    created deteled_from_inbox deteled_from_outbox

我在您的表格中添加了 2 个字段,这两个字段都将以 YES 和 NO 作为值。起初,两个字段都将NO

$you=$_COOKIE['username'];     
$st= "SELECT* FROM mbox WHERE sentto='$you' AND deteled_from_inbox='NO' ORDER BY ID DESC LIMIT 10";
$you=$_COOKIE['username'];     
$st= "SELECT* FROM mbox WHERE sentto='$you' AND deteled_from_outbox='NO' ORDER BY ID DESC LIMIT 10";

当用户从收件箱中删除数据时,您实际上将使用YES更新deteled_from_inbox,因此它不会显示在收件箱部分中。由于我们没有接触deteled_from_outbox因此它将显示在发件箱侧。

这可能不是最强大的解决方案,但它是一个相当实用的解决方案,并且不需要您对数据库结构进行任何更改。

更改删除功能。不要删除数据库中的行,而是执行一些检查。确定是发件人还是收件人在进行删除。如果发件人正在删除,请检查是否sentto == null 。如果是,请删除该行。否则,设置sentby = null 。反之亦然。

我假设您在用户按删除时发布消息 ID。还假设您正在使用 PDO。让我知道这个假设是否错误。

删除.php

$link = new 'PDO... // blah blah connection stuff
$id = $_POST['id'];
$messageSELECT = $link->prepare("SELECT `sentby`,`sentto` FROM `mbox` WHERE ID = :id");
$messageSELECT->bindValue(':id',$id,'PDO::PARAM_INT);
$messageSELECT->execute();
$msgInfo = $messageSELECT->fetchAll();
$msgDELETE = null;
if($you == $msgInfo['sentby'] && empty($msgInfo['sentto'])){
  $msgDELETE = $link->prepare("DELETE FROM `mbox` WHERE ID = :id");
} elseif($you == $msgInfo['sentby'] && !empty($msgInfo['sentto'])){
  $msgDELETE = $link->prepare("UPDATE `mbox` SET `sentby` = NULL WHERE ID = :id");
} elseif($you == $msgInfo['sentto'] && empty($msgInfo['sentby'])){
  $msgDELETE = $link->prepare("DELETE FROM `mbox` WHERE ID = :id");
} elseif($you == $msgInfo['sentto'] && !empty($msgInfo['sentby'])){
  $msgDELETE = $link->prepare("UPDATE `mbox` SET `sentto` = NULL WHERE ID = :id");
} else {
  // Shouldn't happen
}
$msgDELETE->bindValue(':id',$id,'PDO::PARAM_INT);
$msgDelete->execute();

添加一个像has_mail这样的列,其默认值像AB,这意味着两个用户都有邮件。现在,如果有人从他们的输入/输出框中删除,那么特定的A/B将被删除。

$st= "SELECT* FROM mbox 
      WHERE sentto='$you' and has_mail LIKE '%". $you . "' ORDER BY ID DESC LIMIT 10";
$st= "SELECT* FROM mbox 
      WHERE sentby='$you' and has_mail LIKE '". $you . "%' ORDER BY ID DESC LIMIT 10";

现在,当两个字段都为空时,您可以从数据库中删除消息:

DELETE FROM mbox WHERE LENGTH(has_mail) < 1 

以您当前的数据库结构,不,您不能这样做。让我们从改变你的一些结构开始,以实现你想要的。

1. 添加已删除的字段

首先要做的是添加一个已删除的字段,它是 ENUM(Y, N)。表的结构将如下所示。

tblMessage(id, message, sentby, sentto, created, deleted)

现在,通过删除字段,它允许接收者删除他们的消息,而发送者仍然保留他们的消息。问题是它不允许发件人从发件箱中删除其邮件。

发件箱

SELECT * FROM message WHERE sentby = $you

收件箱

SELECT * FROM message WHERE sentto = $you AND deleted = 'N'

2. 制作两张桌子

为了使其更加灵活 (1) 以便发件人可以从其发件箱中删除邮件,但接收仍然可以将邮件

保留在其收件箱中 (2) 以便收件人可以从其收件箱中删除邮件,并且发件人仍然可以将其发送到其发件箱中。

 tblInbox(id, sendby, message, created, deleted)
 tblOutbox(id, sendto, message, created, deleted)
我认为

使用多个表(每个用户一个)来存档可能是最好的选择。如果你只使用一张桌子,那么随着时间的推移它会变得非常大。


我建议的解决方案是将表结构编辑为:

id    owner    message    sentby    sentto    created

这样,当用户创建邮件时,将创建两条记录:发件人的副本和收件人的副本

当用户 A 向用户 B 发送消息"良好工作"时,查询将是:

发送消息.php

$you=$_COOKIE['username'];
$recipient="UserB";
$st1="INSERT INTO tbl_msg VALUES ($id,'$you','Good Job','$you','$recipient','$time)";
$st2="INSERT INTO tbl_msg VALUES ($id,'$recipient','Good Job','$you','$recipient','$time)";

收件箱.php

$you=$_COOKIE['username'];
$st= "SELECT * FROM mbox WHERE sentto='$you' AND owner='$you' ORDER BY ID DESC LIMIT 10";

发件箱.php

$you=$_COOKIE['username'];
$st= "SELECT * FROM mbox WHERE sentby='$you' AND owner='$you' ORDER BY ID DESC LIMIT 10";

删除.php

只需删除所有者='$you' 从 MBOX 中删除,其中条件 1=值 1 且所有者='$you'


基本上,我的解决方法是这样的:当用户发送邮件时,我们将两封邮件插入数据库(一份用于收件人的收件箱,另一份用于发件人的发件箱)

当用户删除他/她的邮件时,它不会从另一个人的收件箱/发件箱中删除,因为每个用户都有自己的邮件副本