Downline-System in PHP berechnen?

bofh1337

Erfahrenes Mitglied
Moin :D
Ich stehe gerade vor einem Brainstorm, aber einem gigantischen :D

Ich bin gerade dabei, ein Downline/Referal-System zu bauen, welches nur 1 SQL-Query benötigt, ganz egal wie viele Referal-Ebenen es gibt. Mit nur 1 SQL-Query habe ich ja alle Datensätze, die ich brauche, der Rest sollte mit PHP gemacht werden.

Solche System gibt es zwar wie Sand am Meer, diese sind aber mehr als nur laienhaft Entwickelt und verursachen bei (zb. 10 Ebenen) eine nicht zu unterschätzende Last am Server (teilweise bis zum Timeout und kompletter Seiten-Stillstand).

Meine Datenbank sieht so aus:

uid => user-id des users
uid_ref => user-id des users, welcher geworben wurde
Code:
INSERT INTO `downline` (`uid`, `uid_ref`) VALUES
(3, 4),
(3, 5),
(4, 7),
(4, 8),
(6, 9),
(8, 10);

User 3 hat also User 4,5 geworben, User 4 hat 7,8 geworben und User 8 hat 10 geworben, macht zusammen 3 Referal-Ebenen (2 in der 1. Ebene, 2 in der 2. Ebene und 1 in der 3. Ebene),- eingestellt sind 4 Ebenen, die 4. Ebene ist also beim User 3 leer.

Weiß jemand, ob so etwas überhaupt geht? Ich habe Ebene 1 und 2 sauber als HTML-Ausgabe, aber Ebene 3 und 4 spinnen.

Wäre da Nested Trees mit MySQL Sinnvoller als es im PHP zu machen?
 
Das Zauberwort ist wohl ne rekursive Funktion. Natürlich musst du gucken, dass du da nicht irgendwie in endlosschleifen landest, zB wenn durch nen Eingabefehler auf einmal User 10 den User 3 geworben hat.

Zeig mal wie du die Ausgabe bis jetzt geregelt hast.
 
Stimmt, aber daran habe ich schon gedacht, es werden deshalb nur Daten aus der Datenbank geholt, die größer als die eigene User-ID sind (denn die User, welche User 3 wirbt, haben logischerweise eine höhere User-ID als User 3) ;)
Und das Feld "uid_ref" ist Unique,- User 12 kann ja nicht von 2 verschiedenen anderen Usern geworben werden ;)
 
Wie hast du denn deine Ausgabe geregelt? Rufst die Daten aus der DB ab und speicherst die in einem Array() nehme ich an? Dann hast du ne Funktion mit der du sortieren willst oder wie? Bisschen wenig Input...
 
Hallo :)
Das ganze habe ich heute schon fertig Programmiert, ich brauche zwar für jede Ebene 1 SQL-Query, so war es aber um ein vielfaches leichter gewesen ;)

Da wird dann auch gleich das Array um einige Statistiken erweitert ;)


Code:
   public function getDownlineRows ($uid, $ebene = 1, $down = null)
    {
        $i = 0;
        $result = $this->db->setQuery ('SELECT d.uid_ref, u.uname, DATE_FORMAT(u.last_activity, "%d.%m.%Y - %H:%i:%s") AS last_activity,
            s.*
            FROM ' . $this->db->quoteName ('#__downline') . ' AS d
                LEFT JOIN ' . $this->db->quoteName ('#__users') . ' AS u
                    ON (d.uid_ref = u.uid)
                LEFT JOIN ' . $this->db->quoteName ('#__users_stats') . ' AS s
                    ON (d.uid_ref = s.uid)
                WHERE d.uid = ' . (int) $uid);
        if ($this->db->loadNumRows ($result))
        {
            $row = $this->db->loadAssoc ($result);
            while ($row)
            {
                $down['ebene' . $ebene][$i]['uid'] = $row['uid_ref'];
                $down['ebene' . $ebene][$i]['uname'] = $row['uname'];
                $down['ebene' . $ebene][$i]['last_activity'] = $row['last_activity'];
                $down['ebene' . $ebene][$i]['startcredits_received'] = $row['startcredits_received'];
                $down['ebene' . $ebene][$i]['stats_clickrate_pm'] = $this->statistics->calcClickRate ($row['paidmail_received_complete'], $row['paidmail_confirmed_complete']);
                $down['ebene' . $ebene][$i]['stats_clickrate_pm_today'] = $this->statistics->calcClickRate ($row['paidmail_received_today'], $row['paidmail_confirmed_today']);
                $down['ebene' . $ebene][$i]['stats_clickrate_questionmail'] = $this->statistics->calcClickRate ($row['questionmail_received_complete'], $row['questionmail_confirmed_complete']);
                $down['ebene' . $ebene][$i]['stats_clickrate_questionmail_today'] = $this->statistics->calcClickRate ($row['questionmail_received_today'], $row['questionmail_confirmed_today']);
                $down['ebene' . $ebene][$i]['stats_jackpot'] = $row['stats_jackpot'];

                $down = self::getDownlineRows ($row['uid_ref'], $ebene + 1, $down);
                $row = $this->db->loadAssoc ($result);
                $i++;
            }
        }
        return $down;
    }


Irgendwann wird es mal fertig...ich sitze ja schon über 2 Jahre an dem Script :D
 
Zuletzt bearbeitet:
OMG, das übersteigt meine momentanen SQL-Skills ein wenig :D

Ich habe zwar schon Querys mit 37 Bedingungen über 9 verschiedene Tabellen gebaut, aber so etwas noch nie :D

Aber im Moment habe ich ein wenig Stress, in meinem CMS wurde der Admin ausgelogt, deshalb lief der Debug-Modus ncht mehr und xdebug habe ich wegen PHPMyAdmin abgeschaltet :D
 
Zuletzt bearbeitet:
Zurück