ugrás a tartalomhoz

Hozzászólások sorszámozása fórumban

Tanul0 · 2009. Jan. 7. (Sze), 13.10
Hi!

Jelenleg egy fórumot fejlesztek, nos a kérdésem a következő lenne:

Adott 1 fórum, azon belül egy topik, azon belül a hozzászólások.
Nos én a hozzászólásokat szeretném sorszámozni 1,2,3... Erre nem nagyon van öteletem, hogy hogyan tudnám megvalósítani. Jelenleg a hozzászólás id-jét iratom ki, de ez elég csúnya, hogy mondjuk 45-ös sorszámmal kezdődik egy topikon belül az első hozzászólás.

a mysql tábláim így néznek ki:

CREATE TABLE IF NOT EXISTS `forumok` (
`forumID` int(14) NOT NULL auto_increment,
`forumnev` varchar(255) NOT NULL,
`kategoria` int(14) NOT NULL default '0',
`info` text NOT NULL,
`datum` varchar(50) NOT NULL default '0000.00.00.',
`zart` int(11) NOT NULL default '0',
`felhID` int(14) NOT NULL,
PRIMARY KEY (`forumID`)
) ENGINE=MyISAM DEFAULT CHARSET=UTF-8 AUTO_INCREMENT=8 ;

CREATE TABLE IF NOT EXISTS `forumtema` (
`temaID` int(14) NOT NULL auto_increment,
`kategoria` int(14) NOT NULL default '0',
`temanev` varchar(255) NOT NULL,
`info` text NOT NULL,
`zart` int(11) NOT NULL default '0',
`datum` varchar(50) NOT NULL default '0000.00.00.',
`forumID` int(14) NOT NULL,
`felhID` int(14) NOT NULL,
PRIMARY KEY (`temaID`)
) ENGINE=MyISAM DEFAULT CHARSET=UTF-8 AUTO_INCREMENT=9 ;


CREATE TABLE IF NOT EXISTS `forumkomment` (
`kommentID` int(14) NOT NULL auto_increment,
`temaID` int(14) NOT NULL default '0',
`felhID` int(14) NOT NULL default '0',
`komment` text NOT NULL,
`datum` varchar(50) NOT NULL default '0000.00.00.',
`valasz` varchar(255) NOT NULL default '0',
`forumID` int(14) NOT NULL,
PRIMARY KEY (`kommentID`)
) ENGINE=MyISAM DEFAULT CHARSET=UTF-8 AUTO_INCREMENT=35 ;

Várom az ötleteket, hogy miként tudnám megoldani.
 
1

rang

Drawain · 2009. Jan. 7. (Sze), 13.39
Szerintem vegyél fel egy újabb mezőt (mondjuk rang), ami azt mondja meg hogy a hozzászólás hányadik lesz az adott témában. Mikor hozzáadsz egy új kommentet megnézed melyik volt a témán belül az utolsó rang, növeled egyel és kész. Ezzel az is könnyen megoldható, hogy valaki válaszolni tudjon egy adott hozzászólásra, mert a rangok már nem változnak a későbbiekben.
2

Sikerült :)

Tanul0 · 2009. Jan. 7. (Sze), 14.14
Sikerült megcsinálni

$sorszamoz=mysql_fetch_array(lekerdez("SELECT * FROM forumkomment WHERE temaID='$temaid' ORDER by sorszam DESC"));
$sorszam=$sorszamoz['sorszam']+1;
köszi az ötletet :)
4

sql injection

gex · 2009. Jan. 7. (Sze), 14.23
sokszor elhangzott már itt, néz utána a címben szerepló témának. (a múltkori témád után is akartam javasolni)
3

hááát

gex · 2009. Jan. 7. (Sze), 14.22
Ezzel az is könnyen megoldható, hogy valaki válaszolni tudjon egy adott hozzászólásra, mert a rangok már nem változnak a későbbiekben.

miért, az id-val nem könnyű megoldani? az id változik?

szerintem hülyeség felvenni adatbázisba a sorszámot, ez a view réteg feladata, egyszerűen kell egy változó, amit a válaszok kiírásának ciklusmagjában növelsz aztán kiírsz.

szerk: ráadásul a moderáció igenis változtathatja a sorrendet és a végén ugyanúgy 45-tel fog kezdődni a listázás.
5

Moderálással nem változik,

Tanul0 · 2009. Jan. 7. (Sze), 14.41
Moderálással nem változik, csak akkor ha az utolsó hozzászólást törlöd, ha valamelyik köztes hsz-t törlöd akkor ott kimarad az a szám, ami szerintem nem vészes, ha egy változót létrehozok a while függvény alatt, akkor rendezésnél nem fog változni a sorszám tehát ami legfölül van mindig az lesz az 1-es. Meg lehet oldani, hogy ne az legyen, pl megszámolom összesen hány komment van és ASC rendezésnél kivonom az összes kommentből azt a változót amit növelek. De így a válasz funkciót nem olyan esztétikusan lehet megoldani mint így adatbázisból.

Ezzel próbálkoztam én is először, ez csak az én egyéni véleményem. Az adatbázisos megoldás nekem jobban bejön
6

nem változik, csak nem egyenletes

gex · 2009. Jan. 7. (Sze), 15.06
Moderálással nem változik
igen, rosszul fogalmaztam, nem változni fog, hanem nem lesz egyenletes. most is ez a problémád, legalábbis a témanyitó hozzászólás alapján.
ha egy változót létrehozok a while függvény alatt, akkor rendezésnél nem fog változni a sorszám tehát ami legfölül van mindig az lesz az 1-es
mi ezzel a probléma? nem ezt akartad?
megszámolom összesen hány komment van és ASC rendezésnél kivonom az összes kommentből azt a változót amit növelek
ezt most így nem értem. :)
7

megszámolom összesen hány

Tanul0 · 2009. Jan. 7. (Sze), 15.28
megszámolom összesen hány komment van és ASC rendezésnél kivonom az összes kommentből azt a változót amit növelek.


Ezzel csak az akartam

két féle nézet van: legutolsó hozzászólás legyen felül vagy a legelső.
while függvénybe: $n=n+1;
Ha a legelső van felül aminek a sorszáma n=0+1, akkor ez stimmel, a második n=n+1.


De ha a legutolsó hsz van felül ami most legyen a második hsz(összesen két hsz-van), tehát annak a sorszáma lesz az n=1, ami nem jó mivel ez az utolsó komment és nem az első.

Ezt meg lehet oldani, úgy hogy megnézem, hogy összesen hány hsz van tehát
$n=$n+1;
$osszes=mysql_num_rows(...hozzaszolasok...);
$n=$osszes-$n;

de ez nem a legjobb szerintem.
8

kivonás

gex · 2009. Jan. 7. (Sze), 15.58
az idő-szerinti rendezés (i+=1;) analógiájára, ha fordítva rendezed akkor nem hozzáadsz, hanem kivonsz egyet (i-=1;).

// idő szerint
$i = 0;
foreach ($comments as $comment) {
    $i += 1; // növeled a segédváltozót
    echo $i . '. hozzászólás:';
    echo 'idő: ' . $comment['date'];
    echo $comment['text'];
}

// fordítva
// vagy sql-ben fordítva rendezed, vagy pl: $comments = array_reverse($comments);
$i = count($comments) + 1;
foreach ($comments as $comment) {
    $i -= 1; // csökkented a segédváltozót
    echo $i . '. hozzászólás:';
    echo 'idő: ' . $comment['date'];
    echo $comment['text'];
}
kb ennyi az egész, nem nagy ördöngösség. persze ez csak egy csontváz, a végleges verziót ki kell egészíteni pl htmlspecialchars függvénnyel a biztonság miatt, html tag-ekkel, dátumformázással, stb.
9

nem egészen értem

Drawain · 2009. Jan. 7. (Sze), 16.16
Nem egészen értem a dolgot :) Ha id alapján tárolsz és mondjuk oldalanként 10 hozzászólás jelenítesz meg, törölgetsz a hozzászólások közül egy-kettőt (moderáció): ezzel igencsak megkeverednek a sorszámok. Így működik rengeteg fórum sajna, és szerintem elvből hibásan.. Ha kitörölsz egy kommentet és egy ciklussal rendeled hozzá a sorszámot akkor a viewban az összes későbbi hozzászólás sorszáma egyel felfele fog csúszni.

És mi van akkor ha lehet válaszolni egy előző kommentre? Mondjuk kimented az id-jét az elemnek és hogyan keresed ki hogy most épp milyen sorszámmal rendelkezik? Főleg ha a forrás és a válasz között néhány hozzászólás törlődik is...

Szerintem semmivel sem bonyolultabb és pazarlóbb felvenni erre egy plusz mezőt az adatbázisban, kényelmesebben lehet keresni így a válaszok közül is.
10

válaszok sorszáma

gex · 2009. Jan. 7. (Sze), 17.33
Ha id alapján tárolsz és mondjuk oldalanként 10 hozzászólás jelenítesz meg, törölgetsz a hozzászólások közül egy-kettőt (moderáció): ezzel igencsak megkeverednek a sorszámok.
nem értem miért keverednének a sorszámok a ciklusomban. ha a válaszok sorszámára vagy kíváncsi, akkor a következő bekezdésben válaszolok.
Ha kitörölsz egy kommentet és egy ciklussal rendeled hozzá a sorszámot akkor a viewban az összes későbbi hozzászólás sorszáma egyel felfele fog csúszni.
ha az összes hozzászólás egy lapon van (legalábbis a model átadja a view-nak az összes hozzászólást), akkor nincs gond, kiírás közben eltárolom egy tömbben az id-sorszám párokat és később fel tudom használni:

$i = 0;
$order = array();
foreach ($comments as $comment) {  
    $i += 1; // növeled a segédváltozót
    $order[$comment['id']] = $i;
    echo $i . '. hozzászólás:';
    if (isset($order[$comment['replyToId']])) {
        echo 'válasz a(z) ' . $order[$comment['replyToId']] . '. hozzászólásra';
    }
    echo 'idő: ' . $comment['date'];
    echo $comment['text'];
}
ha pedig nem egy lapon vannak (és a model nem adja át az összes hozzászólást) akkor ez ugye már nem oldható meg a view rétegen belül, mivel a view nem tudja hogy milyen adat van még, azaz a model-t is módosítani kell. viszont ezt is meg lehet oldani egy új oszlop bevezetése nélkül:
adott egy tábla:
- commentId
- replyToId (annak a hozzászólásnak a commentId-ja amire válaszol)
- commentDate
- comment

SELECT
    c.commentId cid, c.commentDate cdate, c.comment, @rownum1 := @rownum1 + 1 cord, r.commentId rid, r.ord rord
FROM
    (SELECT @rownum1 := 0) rn1,
    comments c
    LEFT JOIN (
        SELECT
            commentId, @rownum2 := @rownum2 + 1 ord
        FROM
            (SELECT @rownum2 := 0) rn2,
            comments
        ORDER BY
            commentDate
    ) r ON c.replyToId = r.commentId
ORDER BY
    c.commentDate
(mysql példa - user variables)
a végére rakhatod a limitet, nem fog összezavarodni. az első sorszámnak (cord) pedig végülis nincs is jelentősége, azt a view is ki tudja számolni a hanyadikoldalez és a hozzászólásokoldalanként változókból. ha az első sorszám nincs akkor ráadásul akárhogyan rendezheted is a hozzászólásokat (oda-vissza) a limit mellett.

nem teszteltem teljesítmény szempontjából és maradhatott is benne hiba.

ja és hogy miért is jó egy új oszlop bevezetése nélkül:
- egyrészt szerintem a sorszámozás nem olyan fontos egy fórumban, használja egyáltalán valaki valamire?
- nem kell újrarendezni moderáláskor, törléskor
11

nincs újrarendezés

Drawain · 2009. Jan. 7. (Sze), 18.41
Dehát nem kell semmit sem újrarendezni moderáláskor / törléskor, pont ez az egész lényege. És ha ilyen kacifántos módon alakítgatod, 3 selectes lekérdezéssel minden oldalhoz, egyszerűen nem hiszem, hogy optimálisabb mint egy új mező! Ne mondd, hogy annyival több helyet foglal az az egy mező, hogy megérje ilyen selecteket írogatni és minden oldalgenerálásnál a viewban sorszámgenerálással foglalkozni.

Nem azt mondtam, hogy nem oldható meg id-kkel, de egyszerűen ezt felesleges bonyolításnak tartom. És azzal amit írtál még mindig megmarad az, hogy komment törlésnél minden utána következő hozzászólás (generált) sorszáma megváltozik. Egyébként szerintem a sorszám fontos, marhára fel tud bosszantani amikor egy fórumba benézek egyszer, az utolsó hozzászólás száma #50, legközelebb benézek, akkor meg #45, de volt két új is, csak a moderátorok töröltek hetet. Na ezt nem oldja meg a lekérdezésed.
12

téma

gex · 2009. Jan. 7. (Sze), 18.50
Dehát nem kell semmit sem újrarendezni moderáláskor / törléskor, pont ez az egész lényege.

a téma arról szól, hogy hogyan lehet megoldani a folyamatos sorszámozást (ami egytől kezdődik és nincs kimaradt szám). ennyi és nem több.

szerk: oké, most olvastam :D
ha valamelyik köztes hsz-t törlöd akkor ott kimarad az a szám, ami szerintem nem vészes
13

téma

Drawain · 2009. Jan. 7. (Sze), 18.55
Amire én mondtam egy szerintem optimális, fejleszthető megoldást, amit már több helyen felhasználtam az említett okok miatt. Az enyém is működőképes volt és te pont azzal reagáltál mert szerinted egy másik megoldás jobb volt :) Na én csupán azt fejtettem ki, hogy miért álltam át már régen a sorszámot adatbázisba mentő kódra - mert mikor annak idején az első fórumot készítettem hamar felvetődtek ezek a kérdések és problémák. Szerintem jó ha valaki előre tervez.

Remélem nincs harag - úgy gondolom így legalább a topiknyitó is megismert két álláspontot és már biztosan meg tudja oldani az említett problémákat :)
14

zárszó

gex · 2009. Jan. 8. (Cs), 03.37
Az enyém is működőképes volt
ezt nem vontam kétségbe.
mert szerinted egy másik megoldás jobb volt
Szerintem jó ha valaki előre tervez.
szerintem is jó, én épp ezért javasoltam a másik megközelítést. szerintem a sorszámozás design-probléma, ami egy esetleges redesign során feleslegessé válik (a minimal jegyében). persze ez az én álláspontom és elismerem, hogy lehet igény a te megoldásodra is. sőt biztosan van is.
Remélem nincs harag
ugyan, már írtam hogy neked volt igazad. ;)
15

:)

Tanul0 · 2009. Jan. 8. (Cs), 22.56
Szép!

Szerintem, a sorszámozás nagyon fontos ezért is tettem fel ezt a kérdést. Én utálom azt, amikor írok egy választ, egy másik válaszra és egymáson belül van 3-4 quote, Ezért gondoltam hogy csak annyit írok ki egy válasz esetén, hogy Válasz erre: #sorszám - Név - Dátum

Mindkét megoldás jó!

gex: A te megoldásodat egy vendégkönyvbe, felhasználók vendégkönyvébe tudnám elképzelni.

Drawain: A te ötletedet 5 perc alatt meg lehet valósítani, és üzembe is helyezni (sikerült is!)

Köszönöm a hasznos kommenteket! bye