Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]System wiadomości
user767
post 24.02.2011, 23:26:02
Post #1





Grupa: Zarejestrowani
Postów: 178
Pomógł: 5
Dołączył: 13.09.2010

Ostrzeżenie: (40%)
XX---


Jak rozwiązać przesyłanie wiadomości między użytkownikami, jeśli już pisałem w php i mysql takie coś, tylko skończyłem w ślepym zaułku, gdzie czekało na mnie co zrobić, gdy użytkownik usunie wiadomość, to drugi też już jej nie ma. Wiadomości zapisywane w bazie danych, w tabeli wiadomości z id użytkownika wysyłającego i odbierającego i innymi polami. Czy jedyne rozwiązanie, to dla każdego użytkownika utworzyć tabelę wiadomości ? Jak wykonać taki system wiadomości między użykownikami.
Go to the top of the page
+Quote Post
IceManSpy
post 24.02.2011, 23:42:49
Post #2





Grupa: Zarejestrowani
Postów: 1 006
Pomógł: 111
Dołączył: 23.07.2010
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Każdy użytkownik musi mieć unikalne ID, które zapisujesz w bazie.
Nawet tutaj na forum tak jest:
http://forum.php.pl/IceManSpy_m50591.html
http://forum.php.pl/user767_m51703.html

To są jakieś numery,. które nas identyfikują w bazie. A w bazie trzymasz informacje od kogo i do kogo jest wiadomość.

Ten post edytował IceManSpy 24.02.2011, 23:43:19


--------------------
Go to the top of the page
+Quote Post
user767
post 25.02.2011, 00:52:12
Post #3





Grupa: Zarejestrowani
Postów: 178
Pomógł: 5
Dołączył: 13.09.2010

Ostrzeżenie: (40%)
XX---


Dobra, a co z usuwaniem wiadomości ? Usunę to wysyłający nie zobaczy w wysłanych. A jak napiszę niewidoczność dla usuniętych to i tak zostaną na serwerze.
Go to the top of the page
+Quote Post
nekomata
post 25.02.2011, 02:00:00
Post #4





Grupa: Zarejestrowani
Postów: 314
Pomógł: 44
Dołączył: 12.11.2010
Skąd: UK

Ostrzeżenie: (0%)
-----


Ja bym to rozwiązał tak :
Załóżmy ze masz 3 kolumnę z bazie (Od, Do, Wiadomość) , wiadomość zostaje wysłana przez użytkownika o ID 666 do użytkownika o ID 997 ,
wiec nasza tabela wygląda tak :

Od | Do | Wiadomosc
----+---+----------------
666|997| Siema zenek

Teraz użytkownik o ID 666 chce usunąć wiadomość z listy wysłanych (jednak chce zęby wiadomość doszła bo to tylko archiwum przecież) i tutaj pojawia się mój pomysl
zamiast usuwać wpisu zastosowałbym UPDATE na danej wiadomość zamieniając ID na np. 0 (konto które stworzyłeś samemu wcześniej albo możesz NULL walnąć)
teraz tylko wystarczy zastosować to samo w druga stronę(jak 997 usunie u siebie a 666 nie usunął) i dodać warunek ze jeśli Od i Do wynoszą 0 , NULL czy co tam wstawiłeś wpis jest usuwany.

EDIT : Chwile po napisaniu tego posta dotarło do mnie ze powyższa metoda będzie mieć jedna wadę, mianowicie jeśli 666 usunie wiadomość u siebie , wiadomość u użytkownika 997 nie będzie miała nadawcy, mógłbyś dodać dwie kolumny typu tinyint np.UsunieteAutor,UsunieteOdbiorca , i jeśli któraś z nich zawiera np. 1 to nie wyświetlać dla danej osoby jeśli NULL to wyświetlać , jeśli obydwa usunięte(znaczy 1 był usunięty a ty dodajesz drugi w tym momencie usuwa cala linie).

Ten post edytował nekomata 25.02.2011, 02:04:34
Go to the top of the page
+Quote Post
wNogachSpisz
post 25.02.2011, 09:18:45
Post #5





Grupa: Zarejestrowani
Postów: 1 233
Pomógł: 87
Dołączył: 6.03.2009

Ostrzeżenie: (40%)
XX---


Cytat(IceManSpy @ 24.02.2011, 23:42:49 ) *
Każdy użytkownik musi mieć unikalne ID, które zapisujesz w bazie.


Nie musi.
Jeśli w tabeli istnieje wartość za pomocą której można unikatowo zidentyfikować użytkownika, np. jego login lub data rejestracji, lub kombinacja dwóch, to po jaką cholere dopychać jeszcze uniqId.
To jest jeden z najczęstrzyszch błędów popełnianych przez "projektantów" baz danych - daja auto-icrement dosłownie wszędzie..
Pole auto-icrement dodajesz kiedy nie ma możliwości unikatowego zidentyfikowania wiersza bazując na innych kolumnach, a takiej identyfikacji wymaga projekt.

Oczywiście, jeśli projekt przewiduje takie coś jak prywatne wiadomości, to ID wydaje się być najlepszym rozwiązaniem, ponieważ zajmuje ono najmniej miejsca, a jeśli ma być często powtarzane w tabeli odpowiedzialnej za PW, to w celu uniknięcia nadmiarowości danych, będzie najlepszym rozwiązaniem.
Należy się jednak bardzo mocno zastanowić, czy np. kombinacja końcówki czasu rejestracji i końcówki numeru IP nie będzie lepsza.
Lepsze w sensie umozliwiające unikatową identyfikację, nie wymagające tworzenia dodatkowej kolumny w tabeli, nie zajmujące zbyt dużo miejsca.
Podejmowanie takich decyzji mozna przyrównać do przeciągania liny.

Osobiście mam w zwyczaju nie usuwać wierszy kiedy wiadomość zostaje usunięta przez użytkownika, zamiast tego nadaje właściwy status.

Ja bym to zrobił tak:

Kod
Od | Do | Wiadomosc   | Status
---+----+-------------+------
666|997 | Siema zenek | 1


Status 1: wiadomość oczekująca na przeczytanie
Status 2: wiadomość przeczytana
Status 3: wiadomość usunięta
Status 4: ....
Status 5: wiadomość systemowa
Status 6: ...

Ten post edytował wNogachSpisz 25.02.2011, 09:32:45
Go to the top of the page
+Quote Post
Wilu88
post 25.02.2011, 09:35:47
Post #6





Grupa: Zarejestrowani
Postów: 158
Pomógł: 6
Dołączył: 7.03.2010

Ostrzeżenie: (0%)
-----


Cytat(wNogachSpisz @ 25.02.2011, 09:18:45 ) *
Nie musi.
Jeśli w tabeli istnieje wartość za pomocą której można unikatowo zidentyfikować użytkownika, np. jego login lub data rejestracji, lub kombinacja dwóch, to po jaką cholere dopychać jeszcze uniqId.
To jest jeden z najczęstrzyszch błędów popełnianych przez "projektantów" baz danych - daja auto-icrement dosłownie wszędzie..
Pole auto-icrement dodajesz kiedy nie ma możliwości unikatowego zidentyfikowania wiersza bazując na innych kolumnach, a takiej identyfikacji wymaga projekt.

Oczywiście, jeśli projekt przewiduje takie coś jak prywatne wiadomości, to ID wydaje się być najlepszym rozwiązaniem, ponieważ zajmuje ono najmniej miejsca, a jeśli ma być często powtarzane w tabeli odpowiedzialnej za PW, to w celu uniknięcia nadmiarowości danych, będzie najlepszym rozwiązaniem.
Należy się jednak bardzo mocno zastanowić, czy np. kombinacja końcówki czasu rejestracji i końcówki numeru IP nie będzie lepsza.
Lepsze w sensie umozliwiające unikatową identyfikację, nie wymagające tworzenia dodatkowej kolumny w tabeli, nie zajmujące zbyt dużo miejsca.
Podejmowanie takich decyzji mozna przyrównać do przeciągania liny.

Osobiście mam w zwyczaju nie usuwać wierszy kiedy wiadomość zostaje usunięta przez użytkownika, zamiast tego nadaje właściwy status.

Ja bym to zrobił tak:

Kod
Od | Do | Wiadomosc   | Status
---+----+-------------+------
666|997 | Siema zenek | 1


Status 1: wiadomość oczekująca na przeczytanie
Status 2: wiadomość przeczytana
Status 3: wiadomość usunięta
Status 4: ....
Status 5: wiadomość systemowa
Status 6: ...


No tak ale co w przypadku gdy tylko nadawca usunął wiadomość ze swojej skrzynki a odbiorca nadal go ma? Wiadomość przyjmie wartość statusu 3 i będzie niewidoczna dla obu użytkowników. Ja bym to rozwiązał na dwa statusy status dla nadawcy i odbiorcy. Nie obciąży to w żadnym stopniu strony a łatwiej będzie operować na wartościach.

Tak samo jeśli tworzysz wiadomość systemową czyli pole status przyjmuje wartość 5 to wyklucza to sprawdzeni czy przeczytana czy nie? I tym samym nie można jej usunąć?

Ten post edytował Wilu88 25.02.2011, 09:37:31
Go to the top of the page
+Quote Post
wNogachSpisz
post 25.02.2011, 09:40:19
Post #7





Grupa: Zarejestrowani
Postów: 1 233
Pomógł: 87
Dołączył: 6.03.2009

Ostrzeżenie: (40%)
XX---


Cytat(Wilu88 @ 25.02.2011, 09:35:47 ) *
No tak ale co w przypadku gdy tylko nadawca usunął wiadomość ze swojej skrzynki a odbiorca nadal go ma? Wiadomość przyjmie wartość statusu 3 i będzie niewidoczna dla obu użytkowników. Ja bym to rozwiązał na dwa statusy status dla nadawcy i odbiorcy.


No i błąd.

status 3: wiadomość usunięta przez nadawce
status 4: wiadomośc usunięta przez odbiorce
status 5: wiadomość usunięta zarówno przez odbiorce jak i nadawce.

Proste.
I obyło się bez dodatkowej kolumny.

Cytat(Wilu88 @ 25.02.2011, 09:35:47 ) *
Nie obciąży to w żadnym stopniu strony a łatwiej będzie operować na wartościach.


Obciązy w bardzo konkretny sposób:
Tabela będzie większa, jaj przeszukiwanie zajmie więcej czasu,
bezpośrednio spowoduje to spadek wydajności systemu.

Ten post edytował wNogachSpisz 25.02.2011, 09:44:07
Go to the top of the page
+Quote Post
Wilu88
post 25.02.2011, 09:43:39
Post #8





Grupa: Zarejestrowani
Postów: 158
Pomógł: 6
Dołączył: 7.03.2010

Ostrzeżenie: (0%)
-----


Cytat(wNogachSpisz @ 25.02.2011, 09:40:19 ) *
No i błąd.

status 3: wiadomość usunięta przez nadawce
status 4: wiadomośc usunięta przez odbiorce
status 5: wiadomość usunięta zarówno przez odbiorce jak i nadawce.

Proste.
I obyło się bez dodatkowej kolumny.


Ale dalej mieszasz np. ze sprawdzeniem czy przeczytana? Nie możesz tego wrzucić do tego samego pola co sprawdzanie czy jest usunięta czy nie? No bo co jeśli jest przeczytana czyli przyjmuje wartość 2, nadawca ja usunie wtedy przyjmuje wartość 3. I jak teraz sprawdzisz czy odbiorca ją przeczytał?
Go to the top of the page
+Quote Post
wNogachSpisz
post 25.02.2011, 09:46:18
Post #9





Grupa: Zarejestrowani
Postów: 1 233
Pomógł: 87
Dołączył: 6.03.2009

Ostrzeżenie: (40%)
XX---


Cytat(Wilu88 @ 25.02.2011, 09:43:39 ) *
Ale dalej mieszasz np. ze sprawdzeniem czy przeczytana? Nie możesz tego wrzucić do tego samego pola co sprawdzanie czy jest usunięta czy nie? No bo co jeśli jest przeczytana czyli przyjmuje wartość 2, nadawca ja usunie wtedy przyjmuje wartość 3. I jak teraz sprawdzisz czy odbiorca ją przeczytał?


Udajesz prawda?

Status 3: Wiadomość przeczytana, usunięta przez odbiorce
Status 4: Wiadomość przeczytana, usunięta przez nadawce
Status 5: Wiadomość nieprzeczytania, usunięta przez odbiorce
Status 6: ...
Status 7:
Status 8:
Status 9:
Status 10:
Status 11:

Nawet jeśli dojdziesz ze statusami do 10.000, nadal będzie się bardziej opłacać niż kolejna kolumna..

------------------------------------------------------------------------------------------

Możesz też dać coś w stylu liczby dwócyfrowej, gdzie pierwsze cyfra to status dla nadawcy, a druga status dla obiorcy np:

Status: 31: usunięta przez odbiorce, nieprzeczytana
Status: 32: usunięta przez odbiorce, przeczytana
Status: 41: usunięta przez odbiorce, nieprzeczytana
Status: 42: usunięta przez odbiorce, przeczytana

Nadal lepsze rozwiązanie niż dodatkowa kolumna..

Ten post edytował wNogachSpisz 25.02.2011, 09:51:27
Go to the top of the page
+Quote Post
Wilu88
post 25.02.2011, 09:49:52
Post #10





Grupa: Zarejestrowani
Postów: 158
Pomógł: 6
Dołączył: 7.03.2010

Ostrzeżenie: (0%)
-----


Cytat(wNogachSpisz @ 25.02.2011, 09:46:18 ) *
Udajesz prawda?

Status 3: Wiadomość przeczytana, usunięta przez odbiorce
Status 4: Wiadomość przeczytana, usunięta przez nadawce
Status 5: Wiadomość nieprzeczytania, usunięta przez odbiorce
Status 6: ...
Status 7:
Status 8:
Status 9:
Status 10:
Status 11:

Nawet jeśli dojdziesz ze statusami do 10.000, nadal będzie się bardziej opłacać niż kolejna kolumna..


No właśnie nie wydaje mi się aby sprawdzanie za pomocą case 1000 wartości było bardziej wydajne niż dodanie kolejnego pola z jedno znakowym charem. A tutaj musisz przewidzieć wszystkie możliwe kombinacje, a dodanie np kolejnego statusu sprawia że na nowo musisz wszystkie statusy przebudować.

No ale nigdy tego nie robiłem mam dopiero w planach, także może masz rację .Jak zajmę się systemem wiadomości to przetestuje oba sposoby.

Ten post edytował Wilu88 25.02.2011, 09:53:26
Go to the top of the page
+Quote Post
wNogachSpisz
post 25.02.2011, 09:53:40
Post #11





Grupa: Zarejestrowani
Postów: 1 233
Pomógł: 87
Dołączył: 6.03.2009

Ostrzeżenie: (40%)
XX---


Cytat(Wilu88 @ 25.02.2011, 09:49:52 ) *
No właśnie nie wydaje mi się aby sprawdzanie za pomocą case 1000 wartości było bardziej wydajne niż dodanie kolejnego pola z jedno znakowym charem. A tutaj musisz przewidzieć wszystkie możliwe kombinacje, a dodanie np kolejnego statusu sprawia że na nowo musisz wszystkie statusy przebudować.


Nie musisz robić żadnego case.
Wystarczy że dodasz kolejną table w bazie danych, gdzie będziesz miał te wszystkie statusy przetłumaczone na taką formę jaka Ci odpowiada.
Potem wykonujesz odpowiednie zapytanie i baza zwraca nawet 10 kolumn ze statusami dla odbiorcy, nadawcy, kogokolwiek innego.
Jeżeli uznasz że własnie taki format odpowiedzi Ci odpowiada, możesz tak zrobić..

Jeszcze raz powtórze, liczy się wydajność, nie wygoda..

Ten post edytował wNogachSpisz 25.02.2011, 09:55:16
Go to the top of the page
+Quote Post
-Gość-
post 25.02.2011, 12:08:24
Post #12





Goście







Tak pokazywałem
  1. $this -> query="SELECT * FROM osoby WHERE id='$id_od_kogo'";


Odebrane nowe
  1. $query="SELECT * FROM wiadomosci left join wiadomosci_osoby on wiadomosci.id=wiadomosci_osoby.id_wiadomosci


Tak zaznaczałem jako przeczytane
  1. $typ = $r['status'];
  2. $typ_get = "0"; // 0, czyli przeczytana
  3.  
  4. echo "<table border=\"0\">";
  5. echo "<tr><td width=\"350\"><strong>{$r['temat']}</strong>
  6. <br />"; echo $dzien. " ". $mies. " ". $rok. " r. </td> <td width=\"200\">
  7. <a href=\"mail_zapisz.php?od_kogo=$id_od_kogo&typ_get=$typ_get&typ_baza=$typ&id={$r['id_wiadomosci']}\">[ Zobacz ]</a>


Tak pokazywałem przeczytane
  1. $query="SELECT * FROM wiadomosci left join wiadomosci_osoby on wiadomosci.id=wiadomosci_osoby.id_wiadomosci
  2. WHERE (id_do_kogo='$id' AND status='0') AND (typ!='$id_os') ";


Pokazywałem wysłane
  1. $query="SELECT * FROM wiadomosci left join wiadomosci_osoby on wiadomosci.id=wiadomosci_osoby.id_wiadomosci
  2. WHERE (id_od_kogo='$id' AND typ!='$id_os')";


Ile nowych
  1. $query="SELECT * FROM wiadomosci_osoby WHERE (id_do_kogo=$id && status=1) && typ!=$id ";
  2. $wynik2 = mysql_query($query);
  3. $ile_nowych = mysql_num_rows($wynik2);
  4.  
  5. echo "<center>Masz <u>" . $ile_nowych . "</u> nieprzeczytanych wiadomości.<br />";


Ile razem
  1. $query="SELECT * FROM wiadomosci_osoby WHERE (id_do_kogo=$id AND typ!=$id)";
  2.  
  3. $wynik=mysql_query($query);
  4. $ile_razem = mysql_num_rows($wynik);
  5.  
  6. echo "Razem <u>" . $ile_razem . "</u> wszystkich wiadomości.<br /><br />";


Czy jest jakaś opcja, dzięki której gdyby wszystkie status wiadomości przyjął wartość usunięte przez jednego i drugiego użytkownika, usunąć oraz w jakim czasie taką komendę wstawić. Bo ja znam tylko trunkable to czyszczenia tabel, np. tymczasowej pomocniczej dla sesji.
Go to the top of the page
+Quote Post
nekomata
post 25.02.2011, 15:36:26
Post #13





Grupa: Zarejestrowani
Postów: 314
Pomógł: 44
Dołączył: 12.11.2010
Skąd: UK

Ostrzeżenie: (0%)
-----


Cytat(Gość-)
Czy jest jakaś opcja, dzięki której gdyby wszystkie status wiadomości przyjął wartość usunięte przez jednego i drugiego użytkownika, usunąć oraz w jakim czasie taką komendę wstawić. Bo ja znam tylko trunkable to czyszczenia tabel, np. tymczasowej pomocniczej dla sesji.

Sprawdzać przy zmianie statusu na usunięty??np. Autor usuwa wiadomość i przed tym daj zapytanie czy odbiorca usunął wiadomość również , jeśli obydwoje usunęli : dajesz DELETE w zapytaniu .

Ten post edytował nekomata 25.02.2011, 15:37:42
Go to the top of the page
+Quote Post
thek
post 25.02.2011, 16:00:07
Post #14





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Pytanie... A po co mi sprawdzać, czy użytkownik przed wywaleniem czytał wiadomość? Usunął ją to usunął - nieważne co zrobił wcześniej. Chcesz zrobić historię wiadomości? To bez sensu. Jeśli już tak bardzo Ci zależy, to posłuż się maskami:
00000 - 1 cyfra - zapisanie przez nadawcę, 2 cyfra - usunięcie przez nadawcę, 3 cyfra odczytanie przez odbiorcę, 4 cyfra - zapisanie przez odbiorcę, 5 cyfra - usunięcie przez odbiorcę
Tam gdzie prawda ustaw 1, jeśli false to niech jest 0. Gdy 2 i 5 cyfra są na 1 to usuwaj wiadomość. Jeśli tylko jedna z nich jest na false to jej nadawcy lub odbiorcy nie pokazuj i tyle. Zamiast masek możesz użyć czegokolwiek, ale mechanizm jest identyczny.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
wNogachSpisz
post 25.02.2011, 16:01:25
Post #15





Grupa: Zarejestrowani
Postów: 1 233
Pomógł: 87
Dołączył: 6.03.2009

Ostrzeżenie: (40%)
XX---


Cytat(thek @ 25.02.2011, 16:00:07 ) *
Jeśli już tak bardzo Ci zależy, to posłuż się maskami:


Maska, brakowało mi terminu "maska" w moich powyższych wywodach ;p
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 12.06.2025 - 17:23