["PHP/MySQL"] Een (uitgebreid) Forum Maken

Pagina: 1
Acties:
  • 104 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • BarthezZ
  • Registratie: Juli 2004
  • Niet online

BarthezZ

anti voetbal en slechte djs!

Topicstarter
offtopic:
Ik heb op een andere site al een thread als deze gemaakt, en daaruit bleek dat veel mensen tegen ongeveer hetzelfde probleem aan liepen, hier dus een poging bij de echt slimme mensen *slijm*


Tijdens het maken van mijn eigen forum liep ik tegen een redelijk ingewikkeld probleem aan: de Topic Highlights (ander icoontje oid als er nieuwe posts zijn in een topic)
Het grote struikelblok waar ik tegenaanloop is de logica van het highlight gebeuren. Ik heb al enige dingen geprobeerd, maar die werkten bijvoorbeeld niet bij uitzonderingen, werkte zeer inefficient met waanzinnig veel query's, of klopten gewoon niet.

Nu de vraag dus: Hoe pakken jullie een eigen forum met topic highlight aan?

Wat ik al geprobeerd heb:

Van elk topic bijhouden (in de database) per user of die het gelezen heeft, als er een nieuwe post is word in de hele tabel geupdate dat topic X een nieuwe post heeft, all read functie door een timestamp op te slaan van topics die "outdated" zijn
- Nadelen: bijzonder omslachtig, veel query geweld, en daardoor dus sloom en inefficient

Bovenstaande met enige aanpassingen en dan opgeslagen in cookie's, minder db geweld, veel client side geweld
- Nadeel: ik wil dat de topic highlight ook vanaf meerdere systemen bereikbaar is

*nog wat andere ideeen die naderhand te omslachtig waren en niet de moeite zijn hier te posten

Ik sta open voor alle ideen :)

Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Wat dacht je van gewoon de datum bijhouden van de laatstebezoek van de gebruiker (sessie/koekie), en deze vergelijken met de date van de laatste reply per topic?

[ Voor 10% gewijzigd door prototype op 28-10-2006 23:21 ]


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:45
Volgens mij kan dit simpel met één query opgelost worden.

- Je houdt bij wanneer de user voor het laatst op het forum geweest is.
- Per topic weet je de datum / tijd van de laatste reactie.

Met een IIF / CASE statement in het SELECT statement dat de forum listing ophaalt, kan je direct een indicatie geven of een topic nieuwe reacties bevat of niet.

code:
1
2
3
4
5
6
SELECT CASE WHEN topic.lastreplydate > @lastVisitDate 
                  THEN   0
                  ELSE 1 AS read,
             topic.topictitle
FROM topic
ORDER BY lastreplydate DESC


bv.

T-SQL code, ik weet niet hoe je het doet in MySQL.


edit:
wat prototype zegt dus. :)

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • BarthezZ
  • Registratie: Juli 2004
  • Niet online

BarthezZ

anti voetbal en slechte djs!

Topicstarter
Wat dan een nadeel is dat de volgende situatie kan voorkomen:

User komt naar forum en er is een grote lijst met unread topics,
User klikt 1 willekeurig topic aan, en gaat terug naar de lijst met topics,
Dan zouden of alle topics moeten worden ge un-highlight, of juist geen topic. Wat je dus niet krijgt is gelijk onderscheid tussen unread / read topics.
(dit dus als je alles doet aan de hand van 1 sessie / cookie timestamp, en anders krijg je weer onzinnig veel data, denk ik)

Acties:
  • 0 Henk 'm!

Verwijderd

prototype schreef op zaterdag 28 oktober 2006 @ 23:20:
Wat dacht je van gewoon de datum bijhouden van de laatstebezoek van de gebruiker (sessie/koekie), en deze vergelijken met de date van de laatste reply per topic?
Dan kun je niet per gebruiker per topic opslaan of iemand de laatste reactie gelezen heeft.
En als de TS dat wel wil zit er zeinig anders op dan dus voor een gebruiker ergens bijhouden welk topic hij om hoe laat bekeken heeft. Dat kun je dan ook meteen het beste in een database doen (handig met queries), maar dat is meteen een hele aanslag op je database als het om een druk forum gaat. Als dat niet zo is, of als je dat nog niet weet, kun je het best nog niet gaan optimaliseren. Dat kan altijd nog. Zorg er gewoon voor dat je die functionaliteit netjes gescheiden houdt van de andere code, en als je dan moet aanpassen hoe en waar iets wordt opgeslagen, dan is dat heel eenvoudig en duidelijk.

Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

@Cheatah: Imho is het handiger om gewoon in session/clientside data dat ook bij te houden, welke topics dus read zijn per bezoek (probleem is dat dat wel heel veel kan worden), dus na een bezoek wordt die session data gecleared omdat de laatste bezoek al dat opvangt. Je zou dan gewoon de voorkeur kunnen geven eerst aan de sessie/client data vanuit de presentatielaag code, om wel of niet iets read of unread te laten displayen en dan pas kijken of er nog overige topics zijn die nieuwe reacties hebben gekregen adhv laatste reactie tov laatste bezoek. Wel wat beperkter dan jouw oplossing, maar wel veel liever voor de databaas ;)

[ Voor 11% gewijzigd door prototype op 28-10-2006 23:36 ]


Acties:
  • 0 Henk 'm!

  • mrFoce
  • Registratie: Augustus 2004
  • Laatst online: 09-09 17:18
BarthezZ schreef op zaterdag 28 oktober 2006 @ 23:25:
Wat dan een nadeel is dat de volgende situatie kan voorkomen:

User komt naar forum en er is een grote lijst met unread topics,
User klikt 1 willekeurig topic aan, en gaat terug naar de lijst met topics,
Dan zouden of alle topics moeten worden ge un-highlight, of juist geen topic. Wat je dus niet krijgt is gelijk onderscheid tussen unread / read topics.
(dit dus als je alles doet aan de hand van 1 sessie / cookie timestamp, en anders krijg je weer onzinnig veel data, denk ik)
Zet er dan een timeout op?..

Die doe je dan wel via een cookie .

bv. Je schrijf naar de cookie de tijd van de timestamp en geeft de cookie een levensduur van 30 minuten o.i.d. Vervolgens kijk je of er een cookie is, zo nee -> highlighten en cookie aanmaken.
Cookie gevonden, tijd checken. Is de tijd meer dan 30 min geleden, niet highlighten.

[ Voor 16% gewijzigd door mrFoce op 28-10-2006 23:38 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Als je het client-side opslaat dan kun je niet achter een andere machine inloggen en de gegevens van je andere sessie opvragen. Het zal dus wel server-side moeten, en als je dan toch met een database werkt is dat ook de beste plek om dat soort gegevens op te slaan.

Acties:
  • 0 Henk 'm!

  • BarthezZ
  • Registratie: Juli 2004
  • Niet online

BarthezZ

anti voetbal en slechte djs!

Topicstarter
Dus als ik prototype goed begrijp:

Nieuw Bezoek,
Uit Db/cookie/whatever word de laatste visit gehaald.

Aan de hand daarvan zou je dan met een (zeer beperkte) database de net gelezen topics kunnen markeren als gelezen.

Zeker een oplossing die ik ga overwegen!
Verwijderd schreef op zaterdag 28 oktober 2006 @ 23:36:
Als je het client-side opslaat dan kun je niet achter een andere machine inloggen en de gegevens van je andere sessie opvragen. Het zal dus wel server-side moeten, en als je dan toch met een database werkt is dat ook de beste plek om dat soort gegevens op te slaan.
Ja, database is dan de beste oplossing, maar welke data, hoeveel data, al dat soort dingen zijn toch dingen die ik zeker mee wil nemen om de performance een beetje degelijk te houden


Kleine Note:
Bij het schrijven van 't forum hou ik in mijn achterhoofd dat het veel bezocht gaat worden

[ Voor 55% gewijzigd door BarthezZ op 28-10-2006 23:40 . Reden: Quote van Cheatah ]


Acties:
  • 0 Henk 'm!

Verwijderd

userID, topicID, timestamp
hoeveel data
alles tot een week oud ofzo?
al dat soort dingen zijn toch dingen die ik zeker mee wil nemen om de performance een beetje degelijk te houden
Dat kan ik me voorstellen. Maar zorg voor de juiste indexen op je tabellen, en dan mag het niet zo'n groot probleem worden. Als het echt te gek wordt bij het inserten (dat trager wordt bij grote tabellen met indexen) kun je gaan voor delayed inserts, of je kunt insert queries opsparen en eens in de zoveel tijd (bijvoorbeeld een halve minuut) doen. Maar dat is eenvoudig aan te passen mocht dat nodig zijn.
Kleine Note:
Bij het schrijven van 't forum hou ik in mijn achterhoofd dat het veel bezocht gaat worden
Wishful thinking? Premature optimization?
Caching is een bitch om goed aan te pakken.

Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op zaterdag 28 oktober 2006 @ 23:36:
Als je het client-side opslaat dan kun je niet achter een andere machine inloggen en de gegevens van je andere sessie opvragen. Het zal dus wel server-side moeten, en als je dan toch met een database werkt is dat ook de beste plek om dat soort gegevens op te slaan.
Daar heb je een punt, was ik even voor het gemak vergeten. ;)
Nee in dat geval zou ik dan ook voor een database kiezen.
Ja, database is dan de beste oplossing, maar welke data, hoeveel data, al dat soort dingen zijn toch dingen die ik zeker mee wil nemen om de performance een beetje degelijk te houden
Een table die bijhoudt welke topics door welke user gelezen is volstaat dan toch?
[edit]
Wat Cheatah dus zegt, daarbij zou ik wel nog even willen toevoegen dat je misschien ook die table eens (periodiek) wil clearen wanneer het laatste bezoek deze 'situaties' al in beschouwing neemt. Anders is het redundant...

[ Voor 12% gewijzigd door prototype op 28-10-2006 23:51 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op zaterdag 28 oktober 2006 @ 23:46:
Wishful thinking? Premature optimization?
Caching is een bitch om goed aan te pakken.
Optimalisatie is nooit prematuur. Achteraf optimaliseren is veel lastiger en tijdrovender dan vanaf het begin uitgaan van een zo optimaal mogelijk ontwerp.

Acties:
  • 0 Henk 'm!

Verwijderd

je kunt ook een client-side java script gebruiken welke nadat een topic geopened is, na 5 seconden
via een iframe ofzo een php bestand aanroepen welke dan het id van het open topic opslaat in een
tabel van de op dat moment ingelogde user.

dus stel je hebt:
login.php, deze logt de user in en maakt de sessie etc.
topic.php, deze geeft het topic weer en gebruikt een javascript om een klein iframpje te laden.
mark_read.php, deze pagina wordt aangeroepen door de iframe als: mark_read.php?topic_id=123,
checkt of welke user ingelogd is en doet dan een sql-query welke topic 123 toevoegt aan de lijst.
show_topics.php geeft een lijst met topics welke en haalt de volledige lijst uit de user tabel van
topics welke al zijn gelezen, vervolgens gebruik je een php functie zoals in_array of array_search om te kijken welke topics al zijn gelezen.

zo raakt je database niet direct overbelast en weet je welke topics de user al heeft gelezen en welke niet.

Acties:
  • 0 Henk 'm!

  • StephanL
  • Registratie: Juni 2001
  • Laatst online: 26-06 22:08
Je zou ook even de code kunnen checken van phpbb. Ik heb het ooit gevonden in de code van phpbb, en wat ze daar doen zijn een aantal vergelijkingen. Tevens zou ik ook naar andere open source fora kijken zoals SMF.

Acties:
  • 0 Henk 'm!

  • BarthezZ
  • Registratie: Juli 2004
  • Niet online

BarthezZ

anti voetbal en slechte djs!

Topicstarter
StephanL schreef op zondag 29 oktober 2006 @ 10:52:
Je zou ook even de code kunnen checken van phpbb. Ik heb het ooit gevonden in de code van phpbb, en wat ze daar doen zijn een aantal vergelijkingen. Tevens zou ik ook naar andere open source fora kijken zoals SMF.
Bij phpbb heb ik het geprobeert, maar het was zo'n ongelofelijke rotzooi dat ik er niet veel wijs uit kon worden.

@reactie daarboven

Waarom een Iframe? ooit gehoord van een include?
Ik ga dan nog wel proberen de iets "nieuwere" projectjes na te kijken, aangezien die hopelijk een duidelijkere source hebben.

Acties:
  • 0 Henk 'm!

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09 23:18

djc

Ik ben het met Cheatah eens.

That said, volgens mij werken vrijwel alle grote engines zo dat ze bijhouden wanneer de laatste request in je vorige sessie was, en dat vergelijken met de last-modified dat van de topics.

Rustacean


Acties:
  • 0 Henk 'm!

  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 18-08 21:31
Een browser houdt bij op welke links iemand heeft geklikt, met stylesheets kun je voor de verschillende weergaves ook plaatjes gebruiken. Dus wat je kunt doen is in de link iets zetten wat de laatste wijziging weergeeft, dan heb je verder helemaal geen queries of cookies nodig. Nadeel is wel dat dit niet overdraagbaar is van de ene naar de andere computer.

Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

_js_ schreef op zondag 29 oktober 2006 @ 18:33:
Een browser houdt bij op welke links iemand heeft geklikt, met stylesheets kun je voor de verschillende weergaves ook plaatjes gebruiken. Dus wat je kunt doen is in de link iets zetten wat de laatste wijziging weergeeft, dan heb je verder helemaal geen queries of cookies nodig. Nadeel is wel dat dit niet overdraagbaar is van de ene naar de andere computer.
Een browser houdt het ook alleen maar bij van 1 persoon (namelijk de gebruiker). En de links worden dynamisch aangemaakt op een forum (dus vanuit de database). Waar wil je dat 'iets' vandaan halen als het niet in de database mag?

Wat ik zou doen is een M:N tabel maken met de al eerder aangegeven waarden userID, topicID, timestamp. Da's een behoorlijke aanslag op je database (en serverperformance) bij hogere activiteit, maar eventueel kun je dit (en wat andere vaak gebruikte data) op een aparte database (op aparte server) zetten, mocht je daar de beschikking over hebben.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • Johnny
  • Registratie: December 2001
  • Laatst online: 14:39

Johnny

ondergewaardeerde internetguru

Zyppora schreef op maandag 30 oktober 2006 @ 11:05:
[...]


Een browser houdt het ook alleen maar bij van 1 persoon (namelijk de gebruiker). En de links worden dynamisch aangemaakt op een forum (dus vanuit de database). Waar wil je dat 'iets' vandaan halen als het niet in de database mag?
Door de topics een URL geven zoals 'topic/6?[timestamp]' waarbij [timestamp] de laatste wijzigingsdatum van het topic is. Als het topic voor de wijziging bezocht is zal het weer als unvisited worden weergegeven.

Aan de inhoud van de bovenstaande tekst kunnen geen rechten worden ontleend, tenzij dit expliciet in dit bericht is verwoord.


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 12-09 10:59

Zyppora

155/50 Warlock

Johnny schreef op maandag 30 oktober 2006 @ 11:14:
[...]


Door de topics een URL geven zoals 'topic/6?[timestamp]' waarbij [timestamp] de laatste wijzigingsdatum van het topic is. Als het topic voor de wijziging bezocht is zal het weer als unvisited worden weergegeven.
Nu mis je het probleem denk ik. De timestamp van de laatste post is makkelijk per topic in de database te zetten. Het probleem is per user bijhouden wanneer hij/zij een bepaald topic voor het laatst bezocht heeft. Dus als je 100 topics hebt in je forum, and 100 (actieve) users, moet je dus 100x100 = 10.000 relaties bijhouden.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

Verwijderd

Ik zie het voordeel van die werkwijze niet als je dat opweegt tegen de overhead (en daarmee "laadtijd" van een pagina). Als ik dit forum bekijk, lijkt het of ze alle topics met nieuwe posts weergeven als nieuw.. als je er een bekeken hebt, blijft deze zogezegd "nieuw"... totdat een bepaalde tijd is verstreken of je je opnieuw aanmeldt schat ik. Het lijkt me dat je als gebruiker zelf slim genoeg bent om te zien dat je bepaalde topics wel of niet gezien heb. PHPBB doet het inderdaad "beter" door de topics als gelezen aan te duiden als je dat hebt gedaan, maar ik zelf zie hier niet echt meerwaarde in. Misschien is een onderverdeling in nieuw en actief een goede optie. Nieuw indien er een post is in een topic sinds je voor de laatste keer bent aangemeld. Actief is een topic als er de laatste x minuten nog is gepost.
Pagina: 1