[php] threaded reacties met 1 query

Pagina: 1
Acties:

  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Topicstarter
In mijn hk jubel topic ;) http://gathering.tweakers.net/forum/list_messages/316745
Heb ik mooi lopen opscheppen over mijn threaded reactiesysteem die voor het weergegeven maar 1 query nodig heeft, en geen classes gebruikt.
Toen wilden mensen code zijn, en ben ik maar snel iets gaan schrijven ;)

Ik zal eerst de code geven en dan de uitleg. Niet dat het heel erg ingewikkeld is maar toch ;)

[voor de meeste php-ers zal het niet zo'n kunst zijn, voor mij wel als java-er, ik heb veel baat gehad bij de php-help die ik van chem moest downloaden (thx ;) )]
[php]<?
include("../../includes/db.inc.php");
include("../../includes/functions.inc.php");
include("../../includes/session.inc.php");
include("../../includes/querys.inc.php");

// kan natuurlijk niet echt bij een nieuwsbericht
$item_id = $nieuws;
$desiredRight = $leesrecht;

// query moet dadelijk in querys.inc.php
$displayNews = "select n.title,
n.content,u.login, m.code,m.description from news_news n,
user u, media m where news_id = $news_id and n.user_id =
u.user_id and n.media_id = m.id";
$displayReacties = "select u.login,
n.id ,n.parsedcontent, n.edited, n.replyon from
news_reaction n, user u where news_id = $news_id and
n.user_id = u.user_id";

if (!isset($news_id))
{
echo(generateXml($news_id ." is not a valid news number","",""));
}
else
{
$resultset = mysql_query($displayNews) or die(generateXml(mysql_error(), $displayNews, ""));
if (mysql_num_rows($resultset) == 0)
{
echo(generateXml($news_id ." is not a news number that's in use yet",$displayNews,""));
}
else
{
$resultdata = mysql_fetch_array($resultset);

$xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
$xml .= "<news author=\"$resultdata[login]\" title=\"$resultdata[title]\">";
$xml .= "<content>$resultdata[content]</content>";
$xml .= "<media>$resultdata
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<description>$resultdata[description]</description></media>";
            $xml .= "<reactions>" . getReaction($displayReacties, $news_id);
            $xml .= "</reactions>";
            $xml .= "</news>";
            echo($xml);
        }
    }

    function getReaction($query, $news_id)
    {

        $resultset = mysql_query($query) or die(generateXml(mysql_error(), $query, ""));
        while($resultdata = mysql_fetch_array($resultset))
        {
            $reacties[$resultdata[id]] = "<parsedcontent>$resultdata[parsedcontent]</parsedcontent>";
            if ($resultdata[replyon] != 0)
            {
                $reacties[$resultdata[replyon]] .= "%".$resultdata[id];
            }
            else
            {
                $root[$resultdata[id]] = "$resultdata[parsedcontent]";
            }
        }

        //print_r(split("*>",$root[1]));
        $total ="";
        $poging = array_flip($root);
        foreach($root as $value)
        {
            $total .= showReacties($reacties[$poging[$value]],$reacties);
        }
        //return(showReacties($value,$reacties));
        return($total);

    }

    function showReacties($value,$reacties)
    {
        $total= "";
        $total .="<reactie>";
        if($temp = split("%",$value))
        {
            $teller = 0;
            foreach($temp as $v)
            {
                //echo($v. "<br>");
                if ($teller == 0)
                    $total .= $v;
                else
                {
                    $total .= showReacties($reacties[$v], $reacties);
                    //print_r($temparray);
                }
                $teller++;
            }
        }
        else
            $total .= $value;

        $total.="</reactie>";
        return $total;
    }
?>

Waar het om gaat zijn de methodes getReacties en showReacties.
getReacties leest alle reacties uit de database in. Zet ze in een grote array. kijkt of ze een reply zijn op een andere reactie. Als het een reactie is op een andere reactie zijn zet hij achter de tekst van die reactie een * plus zijn eigen nr. Als het geen reactie op een reactie is maar een reactie op de root, dan voegt hem zichzelf ook nog noet aan de root array.
(het * kun je niet gebruiken in je reactie en moet je vantevoren ff replacen voor een ander karakter, en bij het displayen natuurlijk weer terug veranderen.)

als alles ingelezen is, wordt de array omgedraaid. en wordt er met een loop doorheen gelopen, van elke nummer wordt de bijhorende reactie uit de reactie arrat gehaald en deze wordt naar showreacties gestuurd. ShowReacties explode de reactie op *, display het eerste element uit de array. en roept dan recursief showreacties op voor het volgende element in de array

that's it :) pretty simple eh.

en dit komt eruit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<reactions>
  <reactie>
    <parsedcontent>blaat!</parsedcontent> 
   <reactie>
     <parsedcontent>helemaal geen blaat!</parsedcontent> 
     <reactie>
     <parsedcontent>doet ie het?</parsedcontent> 
     </reactie>
   </reactie>
   <reactie>
     <parsedcontent>22222</parsedcontent> 
     </reactie>
  </reactie>
  <reactie>
     <parsedcontent>ff</parsedcontent> 
  </reactie>
 </reactions>

en dit is [een deel van] de databasetabel
code:
1
2
3
4
5
6
parsedcontent        replyon 
blaat!          0
helemaal geen blaat!    1
ff             0
doet ie het?        2
22222           1

Dus het klopt ;)

pff, dat was het hele verhaal, ik hoop dat het een beetje leuk/nuttig was. Ik doe waarschijnlijk een paar dingen vreemd of fout in PHP, maar ja ik ben ook geen die-hard PHP-er ;) Aanvullingen en verbeteringen zijn van harte welkom :)

O ja, je mag deze code natuurlijk gewoon gebruiken :)

  • D2k
  • Registratie: Januari 2001
  • Laatst online: 31-08 10:19

D2k

netjes hoor
ff 1 klein dingetje :)
include() zou ik vervangen door require()
maar voor de rest ziet het er wel goed uit
zal tonite wel ees kijken of ik nog een verbetering kan vinden :) (denk het niet)

Doet iets met Cloud (MS/IBM)


  • Nielsz
  • Registratie: Maart 2001
  • Niet online
lekker hoor :)

  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Topicstarter
mmm, ik zie dat mijn halve debug werk er nog tussen staat :)

  • razor-x
  • Registratie: Februari 2001
  • Laatst online: 05-06 07:37
nice :)

  • Dennis
  • Registratie: Februari 2001
  • Laatst online: 16:55
Voor mijn forum gebruik ik een heel andere techniek. Weet niet of dat in dit geval ook gebruikt zou kunnen worden, maar ik gebruik het dus om alle categorieen en forums in 1 keer uit te lezen, dus met 1 query.

Hij leest alle fora uit, met daarin de gejoinde categorieen. Het is gesorteerd op de categorievolgorde en daarna de forumvolgorde. Met een for-loopje loopt hij door de array heen die de fetch_row terugstuurt. Zodra hij een nieuw categorienummer ziet, maakt hij een balk aan met de categorie (zoals je die dus hier ook op GoT ziet).

Voordeel hiervan is dat ik veel minder databaseverkeer genereer, en ik hoef niet ingewikkeld te doen met private fora. Ook als iemand helemaal geen toegang heeft tot alle fora in een categorie, laat hij die categorie niet zien.

En met 2 queries worden gewoon netjes alle rechten uitgelezen die de persoon heeft.

  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Topicstarter
het probleem is dat je met threaded reactie's werkt, die je ook threaded wilt weergeven.
Als je daar een query voor bedenkt ben je een sql-held!

(ja dusty dit is een uitdaging ;) )
Pagina: 1