Sistema de mensagens no php mysql
mysql
funciona bem no meu site, mas
o meu problema é- quando UserA
envia uma mensagem para UserB
, A mensagem é mostrada para UserB
na sua caixa de Entrada, E A mensagem é mostrada para UserA
em sua caixa de Saída, agora, se por algum motivo UserB
excluiu a mensagem da sua caixa de Entrada e, em seguida, a mensagem é excluída de ambos os lados, eu sou o armazenamento de toda a mensagem na tabela 1, agora o que eu quero alcançar é quando a mensagem é apagada da caixa de entrada ela ainda deve permanecer na caixa de Saída, qualquer ajuda é muito apreciada! obrigado!
a estrutura do quadro é a seguinte:
id message sentby sentto created
caixa de entrada.php
$you=$_COOKIE['username'];
$st= "SELECT* FROM mbox WHERE sentto='$you' ORDER BY ID DESC LIMIT 10";
caixa de saída.php
$you=$_COOKIE['username'];
$st= "SELECT*FROM mbox WHERE sentby='$you' ORDER BY ID DESC LIMIT 10";
11 answers
Acho que pode manter a sua estrutura actual da tabela para o conteúdo da mensagem. Em vez de adicionar em colunas separadas ou bandeiras apagadas, seria melhor ter uma tabela separada para caixas de correio.
Por isso, a sua actual tabela mbox:
id message sentby sentto created
Depois outra tabela para as caixas de correio do utilizador
id user mailbox message_id
Você teria que fazer três inserções totais ao escrever uma mensagem, uma na tabela de mensagens, para cada usuário na tabela user_mailboxes.
Então, os dados da caixa m parecem ... isto:id message sentby sentto created
1 Hi There UserA UserB 2015-01-26
2 Hello Back UserB UserA 2015-01-26
E os dados das Caixas de correio user_ seriam assim:
id user mailbox message_id
1 UserA Out 1
2 UserB In 1
3 UserB Out 2
4 UserA In 2
Isto permite-lhe apagar linhas individuais para a tabela de caixas de utilizador. Isto permitiria também para o futuro complementos, que permite enviar mensagens para vários usuários ao mesmo tempo (Uma nova linha para cada usuário), e permitem que você adicionar mais de uma caixa de correio, se necessário (dentro, Fora, Lixo, Importante, etc).
Para procurar o correio por um utilizador para uma caixa de correio em particular, basta usar um join
SELECT * FROM user_mailboxes LEFT JOIN mbox ON mbox.id = user_mailboxes.message_id WHERE user_mailboxes.user = "$user" AND user_mailboxes.mailbox = "Out";
Você faria precisa de um programa de limpeza à medida que apaga para se certificar de que não existem mensagens órfãs que não existem na tabela user_ mailboxes.
Faça apenas uma coisa adicione dois novos campos na sua tabela existente
- is_sender_ desleted
- is_ receiver_deleted
Se alguém o apagar da caixa de Saída, então faça o valor is_sender_ desviado para 1. Então, quando você mostra os dados na caixa de saída, você apenas lista todos os registros cujo valor de campo is_sender_ desorientado 0.
A mesma situação se alguém a apagar da caixa de entrada, então faça is_receiver_deleted value 1. Por isso, ao mostrar os dados na caixa de entrada, basta listar todos os registos ter is_receiver_deleted o valor é 0.
Espero que esta solução te ajude.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;
Acho que pode resolver todos os teus problemas, porque os utilizadores das mensagens se separaram uns dos outros
Então, para uma mensagem temos de criar 3 inserções como esta: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')
}
Neste caso, para cada utilizador, criamos uma linha separada na Tabela message_user
. Assim, quando o utilizador_1 apagar a mensagem nesta pasta de entrada, marcá-la-emos como 'apagada' e não terá efeito no segundo usuario.
Então, que recebem todas as mensagens do utilizador, temos de executar apenas uma selecção simples como esta:
SELECT *
FROM message m
JOIN message_user mu
ON m.id = mu.message_id
WHERE mu.deleted = 'none'
AND mu.user_id = :user_id
Você pode adicionar uma coluna como "status" na tabela mbox,
Depois; se o utilizador apagar a mensagem, poderá alterar o estado como 1 ou a UserA apagar a mensagem, poderá alterar o estado como 2.
Para a caixa de entrada:
$you=$_COOKIE['username'];
$st= "SELECT* FROM mbox WHERE sentto='$you' AND status <> '1' ORDER BY ID DESC LIMIT 10";
Para a caixa exterior:
$you=$_COOKIE['username'];
$st= "SELECT* FROM mbox WHERE sentby='$you' AND status <> '2' ORDER BY ID DESC LIMIT 10";
Boa sorte.
Em Vez de apagar as mensagens do banco de dados, use o status de uma determinada mensagem
Como SHOWtoSender,SHOWtoReciver,SHOWtoBoth ou SHOWtoNONE
(use o tipo de dados ENUM e padrão como SHOWtoBoth).
Faça alterações na sua tabela como:
hora do Estado do remetente do ID
Adicione uma coluna como has_mail
que tenha um valor predefinido como AB
, o que significa que ambos os utilizadores têm o correio. Agora, se alguém excluído da sua caixa de entrada/saída, em particular A / B será removido.
$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";
Agora pode apagar a mensagem do db quando ambos os campos estiverem vazios:
DELETE FROM mbox WHERE LENGTH(has_mail) < 1
id message sentby sentto created deteled_from_inbox deteled_from_outbox
À tua mesa adicionei 2 campos, ambos terão sim e não como values.At primeiro, ambos os campos serão 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";
Quando o utilizador apagar os dados da caixa de entrada, irá actualizar de facto o deteled_from_inbox
com YES
, por isso não irá aparecer na caixa de entrada part.As não vamos tocar no que vai aparecer no lado da caixa exterior.
Eu acho que pode ser a melhor opção para usar várias tabelas -- uma para cada usuário -- a fim de arquivar isso. Se você usar apenas uma mesa, então as horas extras vai se tornar realmente grande.
A solução que proponho é editar a estrutura da sua tabela em:
id owner message sentby sentto created
Assim, quando um utilizador criar uma mensagem, serão criados dois registos: a cópia do remetente e a cópia do recivier {[[6]}
Quando a UserA enviar a mensagem do UserB "Bom trabalho", a consulta irá be:
Sendmessage.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)";
Caixa De Entrada.php
$you=$_COOKIE['username'];
$st= "SELECT * FROM mbox WHERE sentto='$you' AND owner='$you' ORDER BY ID DESC LIMIT 10";
Caixa de saída.php
$you=$_COOKIE['username'];
$st= "SELECT * FROM mbox WHERE sentby='$you' AND owner='$you' ORDER BY ID DESC LIMIT 10";
Apagar.php
Apague o que o dono diz: "$you". Apagar da mbox onde a condição 1=Valor 1 e dono= '$you 'Basicamente, a minha solução é a seguinte: quando um utilizador envia uma mensagem, introduzimos duas mensagens na base de dados (uma cópia para a caixa de entrada do destinatário e a outra cópia para a caixa de saída do remetente)
Quando um o utilizador apagou a sua mensagem, não será apagada da caixa de entrada/saída da outra porque cada utilizador tem a sua própria cópia da mensagem
Esta pode não ser a solução mais robusta, mas é bastante funcional, e não requer que você faça quaisquer alterações na sua estrutura DB.
Altere a sua função de eliminação. Em vez de apagar a linha na base de dados, faça algumas verificações. Descobrir se é ou não o remetente ou o destinatário que está a apagar. Se o remetente estiver a apagar, verifique se sentto == null
. Se for, apague a linha. Else, set sentby = null
. E vice-versa.
Apagar.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();
1. Adicionar um campo apagado
A primeira coisa a fazer é adicionar um campo apagado onde está ENUM(Y, N). A estrutura da sua mesa será assim.
tblMessage(id, message, sentby, sentto, created, deleted)
Agora, com o campo apagado, permite ao receptor apagar a mensagem e ao remetente manter a mensagem. O problema é que não permite ao remetente para apagar a sua mensagem da sua caixa de saída.
Caixa de saída
SELECT * FROM message WHERE sentby = $you
Caixa de entrada
SELECT * FROM message WHERE sentto = $you AND deleted = 'N'
2. Fazer duas tabelas
De modo a torná-lo mais flexível (1) para que o remetente possa apagar a mensagem da sua caixa de saída, mas receber ainda pode reter a mensagem na sua caixa de entrada (2) para que o destinatário possa apagar a mensagem da sua caixa de entrada, e o remetente ainda a tenha na sua caixa de saída.
tblInbox(id, sendby, message, created, deleted)
tblOutbox(id, sendto, message, created, deleted)
Se você não quiser perder quaisquer dados do seu banco de dados e não quiser alterar o seu banco de dados, mas ainda quer que seus usuários tenham a capacidade de "apagar", suas mensagens, basta adicionar uma string na frente do campo "sentby" ou "sentto". Isto aplica-se se o sentBy e o sentTo tiverem valores de texto
For example:
UserA sents a message to UserB.
in your table you have:
id message sentby sentto created
msgid msg UserA UserB date
Na sua acção" apagar", se isto for feito pelo UserB, adicione uma string" DeleteD - - - " à frente do UserB no campo db sentto. Agora o teu cadáver fica assim:
id message sentby sentto created
msgid msg UserA DeleteD---UserB date
No seu php code make some functions that would check if the string "DeleteD - -" exists in the sentBy or sentTo fields before doing anything else:
function checkForDeleted($str) {
if (strpos($str,'DeleteD---') !== false) {
return true;
}
}
function getUserIfDeleteD($str) {
$user=array();
if(checkForDeleted($str)===true) {
$arr=explode("---",$str);
$user=$arr[1];
return $user;
}
}
Desta forma você "manter" a informação na sua tabela de banco de dados para estar disponível para ambos os usuários, certificando-se de que se o UserB apagar a mensagem enviada pela UserA, então UserA ainda será capaz de ver em sua caixa de saída o Usuário para quem ele enviou a massagem. Se ambos os usuários apagar a mesma mensagem algum tempo depois, então você pode excluir completamente da base de dados.
No caso sentBy e sentTo ter valores userid( inteiros), então eu proponho adicionar apenas um campo no final da tabela
id message sentby sentto created deleted_message_flag
msgid msg UserA_id UserB_id date 00
ALTER TABLE `messages` ADD COLUMN `deleted_message_flag` bit(2) NOT NULL AFTER `created`;
Como funciona o campo acima? Como um indicador binário para sentby e sentto a respeito de quem apagou a mensagem de sua caixa de correio. Se a mensagem não for apagada então o valor é 0 se for apagada então o valor é 1. O primeiro é para o sentBy e o segundo é para o sentTo. Desta forma, você armazena menos dados e cria apenas um campo na sua tabela atual.
Como analisaste OS 2 bits?
deleted_message_flag deleted_from_sentBy deleted_from_sentTo
00 0 0
01 0 1
10 1 0
11 1 1