Zurück   klamm-Forum > Virtual World > Programmierung > FAQ und Archiv

Like Tree1Likes
  • 1 geposted von flaschenkind

Antwort
 
Themen-Optionen
Alt 24.09.2007, 00:21:05   #1
flaschenkind
Erfahrener Benutzer

ID: 118459
Lose senden

Reg: 20.04.2006
Beiträge: 4.530
Standard [PHP/MySQL] Vernünftiges Refsystem

Da ich gerade langeweile habe schreibe ich mal eine kleine Anleitung dazu, wie man am besten ein Refsystem in PHP schreibt. Es gibt schließlich genug "dreckig" programmiere Script, besonders hier bei Klamm. Oft ist auch ein schlecht programmiertes Refsystem eines der Gründe, warum eine Seite soviele Resourcen frisst. Deswegen werde ich jetzt mal eine kleine Erkärung zur Programmierung eines Refsystems schreiben. Ich werde 3 Beispiele posten, 2 schlechte, ein vernünftiges. Es gibt bestimmt noch andere Refsysteme, die auch schlecht oder gut sind, könnt ihr auch gerne noch posten, aber ich gehe jetzt auf diese 3 ein

Anmerkung: Ich werde keine Namen von Script nennen, aus denen ich die Beispiele habe, alleine schon um nciht nachher noch ne Klage wegen Rufmordes zu erhalten. Einige werden diese Strukturen bestimmt wieder erkennen, und ich bitte diese es für sich zu behalten.

In einem Script gibt es z.B. folgende Refstruktur:
Code:
1:
2:
3:
4:
5:
6:
7:
Tabelle Refs: user|ref1|ref2|ref3|ref4... 1 | 0 ... 2 | 0 ... 4 | 0 .... 5 | 3 | 2 | 0 ... 6 | 5 | 3 | 2 | 0 ...
In diesem Beispiel hab ich Userids genommen, im Originalscript werden Usernames verwendet, wovon ich sowieso abrate. Allgemein in jedem Script! Was ist, wenn z.B. jemand seinen Username geändert haben will? Das geht nur, wenn man sich durch sämtliche Tabellen hangelt und alle Usernames ändert. Mit einer Userid hat man dies Problem nicht, da die ID immer gleich bleibt und sich nur der Username bleibt.

Wenn man hier jetzt z.B. die Downline des Users 2 auslesen will, braucht man folgenden Code:
PHP-Code:
1:
2:
3:
4:
5:
6:
for($i 1;$i<=4;$i++){
  ${
'ebene'.$i.'_refs'} = array();
  
$result mysql_query('SELECT `user` FROM `refs` WHERE `ref'.$i.'`=2');
  
$row mysql_fetch_array($result);
  ${
'ebene'.$i.'_refs'}[] = $row['user'];

Dieser Code bräuchte, wenn man wie hier 4 Ebenen verwendet, 4 Querys für das Auslesen der Downline, wenn man genau wissen will wann welcher User in welcher Ebene ist. Man könnte natürlich auch eine Query machen alà
Code:
1:
SELECT `user` FROM `refs` WHERE `ref1`=2 OR `ref2`=2 OR `ref3`=2 OR `ref4`=2
Damit hätte man auch seine komplette Downline, allerdings weiß man nicht genau wer in welcher Ebene ist.

Wenn man jetzt in ein Anmeldungssystem dieses Refsystem einbauen will, so muss man hingehen und von jedem Werber des Werbers den Werber auslesen. Also etwa so:
PHP-Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
$werber_1 2;
for(
$i 2;$i<=4;$i++){ //nur damit jeder Werber auf 0 steht, weil die Schleife unten ja vorzeitig abgebrochen werden kann
  
${'werber_'.$i} = 0;
}
for(
$i 2;$i<=4;$i++){
  ${
'werber_'.$i} = 0;
  
$result mysql_query('SELECT `ref1` FROM `refs` WHERE `user`='.${'werber_'.($i-1)});
  if(!
mysql_num_rows($result){
    break;
  }
  else{
  
$row mysql_fetch_array($result);
  ${
'werber_'.$i} = $row['ref1'];
  }
}
mysql_query('INSERT INTO `refs` (`user`, `ref1`, `ref2`, `ref3`, `ref4`) VALUES (7, '.$werber_1.', '.$werber_2.', '.$werber_3.', '.$werber_4.')'); 
Also gibt es auch bei der Anmeldung keine Vorteile.

Vorteil: Man blickt leicht durch das System hindurch.
Nachteil: Sehr Performancelastig, sowohl beim Anmelden, als auch beim Downline auslesen.
Fazit: Dieses System kann man verwenden, es braucht zwar pro Ebene eine Abfrage beim Downline auslesen, sowie beim Anmelden, aber das ist verkraftbar, im Vergleich zu dem folgenden System. Trotzdem guckt euch nochmal das letzte System an, bevor ihr euch entscheided dieses zu nehmen



Dann gibt es auch noch ein System, welches man nciht nutzen sollte, was aber auch manchmal zum Einsatz kommt (ich meine jetzt über mehrere Ebenen, über eine Ebene ist es ja ok)
Man hat in der Usertabelle eine Spalte "werber". Mehr nicht. Das Script hagelt dann durch die Tabellen, und erstellt ne Downline. Von diesem System ist noch mehr abzuraten, als das obige, da es wirklich unmengen an Abfragen, und somit auch Ressourcen, zieht.

So haben wir z.B. folgende Tabelle "user":
Code:
1:
2:
3:
4:
5:
6:
7:
userid|werber 1 | 0 2 | 1 3 | 2 4 | 3 5 | 3 6 | 5
Sollte selbsterklärend sein.

Wenn man jetzt die Downline auslesen will, muss man rekursiv arbeiten, da es sonst nicht möglich ist das alles genau auszulesen. Man müsste für jeden Werber eine Abfrage nach dessen User machen, es sind also verdammt viele Abfragen. Deswegen ist davon absolut abzuraten. Hier mal ein Beispiel Code:
PHP-Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function getDownline($userid$ebene=1$downline=null){
  
$result mysql_query('SELECT `userid` FROM `user` WHERE `werber`='.$userid);
  if(
mysql_num_rows($result)){
    while(
$row mysql_fetch_array($result)){
      echo 
$row['userid'].'|'.$ebene.'<br />';
      
$downline['ebene'.$ebene][] = $row['userid'];
      
$downline getDownline($row['userid'], $ebene+1$downline);
    }
  }
  return 
$downline;
}
$userid 1;
$downline getDownline($userid); 
Dies ließe sich so lösen, aber wie man sieht, arbeitet diese Funktion rekursiv, wird also immer neu augerufen. So wird die Query für jeden User der Downline einzeln aufgerufen. So sind das bei der Downline von oben 6 Querys, was schon viel zu viel ist, besonders wenn man sich vorstellt, was passieren würde, wenn ein User über alle Ebenen 200 oder mehr User hat.
Allerdings benötigt man bei diesem Refsystem keine weiter Abfrage bei Anmeldungen, zum Werber eintragen oder ähnliches.


Vorteile: Man benötigt keine zusätzlichen Abfragen bei der Anmeldung
Nachteil: Sehr Performancelastig, da für jeden User der Downline eine eigene Abfrage durchgeführt wird.
Fazit: Dieses System ist überhaupt nicht zu empfehlen, da viel zu viele MySQL Abfragen braucht.



Und nun zu dem guten System, welches ich übrigens auch verwende.

Es gibt eine Tabelle "refs", die z.B. so aussieht.
Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
userid | werber | ebene 1 | 0 | 1 2 | 1 | 1 3 | 2 | 1 3 | 1 | 2 4 | 3 | 1 4 | 2 | 2 4 | 1 | 3 5 | 4 | 1 5 | 3 | 2 5 | 2 | 3 5 | 1 | 4
Also es wird für jeden User genau abgespeichert wer der Werber welcher Ebene ist. Für Werberlose gibts den werber 0, der aber in späteren Ebenen nicht mehr aufgeführt wird.

Das sieht auf den ersten Blick verdammt kompliziert aus, ist mit etwas Einarbeitung kein Problem. Im späteren Einsatz kann man dann mit einer (vernünftigen) Query eine perfekte Downline ausgeben.
Um sich in die Downline einzutragen, braucht es dann zwar ein paar Querys mehr, aber ich denke ja mal, dass die Downline häufiger ausgelesen wird, als dasss ein Werber gewechselt wird oder das man sich neu registriert.

Die Downline könnte man dann z.B. so auslesen:
PHP-Code:
1:
2:
3:
4:
5:
6:
7:
for($i=1;$i<=4;$i++){
  ${
'ebene'.$i.'_userid'} = array();
}
$result mysql_query('SELECT `userid`, `ebene` FROM `refs` WHERE `werber`=1');
while(
$row mysql_fetch_array($result)){
  ${
'ebene'.$row->ebene.'_userid'}[] = $row->userid;

So hat man die Downline schön in nem Array, nach Ebenen sortiert.


Vorteil: Gut für die Performance beim Downline auslesen
Nachteil: Schwer zu durchblicken, beim Anmelden oder Werber ändern kostet es ein paar Querys, aber da man das seltener macht als die Downline auslesen, ist es nicht weiter tragisch.
Fazit: Dieses System ist zu empfehlen, wegen seiner guten Performance .


Gesamtfazit: Nehmt das letzte System

Vielen Dank fürs lesen! Ich hoff es hat euch gefallen.


Info am Rande: Ich saß jetzt einige Zeit an dem Tut, es ist spät und ich hatte nen Anstrengenden Tag. Nehmt Fehler hin und weißt mich bitte freundlich darauf hin, damit ich es ändern kann. Die Codes sind auch alle ungetestet, aber sollten funktionieren, bzw. nur kleine Denkfehler, oder Syntaxfehler haben

Wenn der Thread in den FAQ Bereich verschoben wird, fänd ichs toll, damit ihn (hoffentlich) auch einige zu Gesicht bekommen
Smssam gefällt das.

Geändert von flaschenkind (24.09.2007 um 00:26:53 Uhr)
flaschenkind ist offline   Mit Zitat antworten
Alt 24.09.2007, 22:21:32   #2
chrissel
Woohooo!
Benutzerbild von chrissel

ID: 211634
Lose senden

chrissel eine Nachricht über ICQ schicken
Reg: 20.04.2006
Beiträge: 4.495
Rotes Gesicht

Zitat:
Zitat von flaschenkind Beitrag anzeigen
[..]
Stimme ich dir zu
Auch wenn ich in einem anderem Thread mal das System Nr. 2 beschrieben habe, ist halt das einfachste und da der User nicht Informationen über die Anzahl der Ebenen usw. gemacht hat, wäre es bei einer Ebene finde ich auch das beste.

Aber trotzdem eine kl. Anmerkung: Pack es auch noch einmal in dem Thread der Codeschnipsel
chrissel ist offline   Mit Zitat antworten
Alt 25.09.2007, 00:07:41   #3
theHacker
sieht vor lauter Ads
den Content nicht mehr
Benutzerbild von theHacker

ID: 69505
Lose senden

theHacker eine Nachricht über ICQ schicken theHacker eine Nachricht über Skype™ schicken
Reg: 20.04.2006
Beiträge: 22.689
Standard

Zitat:
Zitat von flaschenkind Beitrag anzeigen
Wenn der Thread in den FAQ Bereich verschoben wird, fänd ichs toll, damit ihn (hoffentlich) auch einige zu Gesicht bekommen
Ich bin ja froh, dass sich einer mal die Mühe gemacht hat
Im Crashforum gammelt der alte Thread rum, den ich damals nicht rüberziehen konnte, weil ne Diskussion mit afair über 100 Posts ned so einfach zusammenfassbar is.

Programmierung / FAQ und Archiv
Zitat:
Zitat von flaschenkind Beitrag anzeigen
Nehmt Fehler hin und weißt mich bitte freundlich darauf hin, damit ich es ändern kann. Die Codes sind auch alle ungetestet, aber sollten funktionieren, bzw. nur kleine Denkfehler, oder Syntaxfehler haben
Mir is beim Durchlesen nur n Fehler im Syntaxhighlighting aufgefallen. Die fehlende Klammer hab ich dir schon eingefügt.

So und jetzt ne kleine Verständnisfrage von mir:
Zitat:
Zitat von flaschenkind Beitrag anzeigen
Für Werberlose gibts den werber 0, der aber in späteren Ebenen nicht mehr aufgeführt wird.
WTF sind Werberlose ? Gehts da um den Refback ?
theHacker ist offline   Mit Zitat antworten
Alt 25.09.2007, 00:10:38   #4
flaschenkind
Erfahrener Benutzer

ID: 118459
Lose senden

Reg: 20.04.2006
Beiträge: 4.530
Standard

Zitat:
Zitat von theHacker Beitrag anzeigen
[...]
Dankeschön

Zitat:
Zitat von theHacker Beitrag anzeigen
So und jetzt ne kleine Verständnisfrage von mir: WTF sind Werberlose ? Gehts da um den Refback ?
Ne, ich mein damit Werber-Los, also die, die keinen Werber haben
flaschenkind ist offline Threadstarter   Mit Zitat antworten
Alt 25.09.2007, 00:15:49   #5
theHacker
sieht vor lauter Ads
den Content nicht mehr
Benutzerbild von theHacker

ID: 69505
Lose senden

theHacker eine Nachricht über ICQ schicken theHacker eine Nachricht über Skype™ schicken
Reg: 20.04.2006
Beiträge: 22.689
Standard

Achso. "Werberlos" als Adjektiv. Sag das doch

Brauchen die 'n Eintrag ? Ich würde sogar sagen, die dürften keinen haben, sonst wäre dein System ja nicht mehr konsistent, da du in höheren Ebenen das weglassen willst.
Wenn ich wissen will, ob es einen Werber gibt und die Datenbank liefert kein Resultat, dann bin ich werberlos.

Außerdem würde ein Join zu großen Problemen führen. Bsp:
"Selektiere die Loseguthaben und die Nicknames aller meiner Werber"
Für User 2 (aus deinem Bsp) alles ok. Dieselbe Abfrage für User 1 führt plötzlich zu komischen NULL-Werten, da ein User mit der ID 0 sicher nicht in der Usertabelle mit Nickname und Loseguthaben geführt wird.
theHacker ist offline   Mit Zitat antworten
Alt 25.09.2007, 00:50:25   #6
flaschenkind
Erfahrener Benutzer

ID: 118459
Lose senden

Reg: 20.04.2006
Beiträge: 4.530
Standard

Zitat:
Zitat von theHacker Beitrag anzeigen
Achso. "Werberlos" als Adjektiv. Sag das doch
Stimmt, so hätt ichs ja viel einfacher ausdrücken können xD

Zitat:
Zitat von theHacker Beitrag anzeigen
Brauchen die 'n Eintrag ? Ich würde sogar sagen, die dürften keinen haben, sonst wäre dein System ja nicht mehr konsistent, da du in höheren Ebenen das weglassen willst.
Wenn ich wissen will, ob es einen Werber gibt und die Datenbank liefert kein Resultat, dann bin ich werberlos.
Stimmt, so könnt mans auch machen. Ich hab bis jetzt immer geguckt, obs nicht 0 ist, aber wenn kein Result da ist, weiß mans ja eigentlich auch

Zitat:
Zitat von theHacker Beitrag anzeigen
Außerdem würde ein Join zu großen Problemen führen. Bsp:
"Selektiere die Loseguthaben und die Nicknames aller meiner Werber"
Für User 2 (aus deinem Bsp) alles ok. Dieselbe Abfrage für User 1 führt plötzlich zu komischen NULL-Werten, da ein User mit der ID 0 sicher nicht in der Usertabelle mit Nickname und Loseguthaben geführt wird.
Sowas hab ich noch nie gebraucht, deswegen hatte ich sonnen Fall auch noch nie bedacht. Das mit der 0 hab ich gespeichert, damit es für jeden User mindestens einen Eintrag gibt.
flaschenkind ist offline Threadstarter   Mit Zitat antworten
Alt 25.09.2007, 09:10:58   #7
theHacker
sieht vor lauter Ads
den Content nicht mehr
Benutzerbild von theHacker

ID: 69505
Lose senden

theHacker eine Nachricht über ICQ schicken theHacker eine Nachricht über Skype™ schicken
Reg: 20.04.2006
Beiträge: 22.689
Standard

Zitat:
Zitat von flaschenkind Beitrag anzeigen
Das mit der 0 hab ich gespeichert, damit es für jeden User mindestens einen Eintrag gibt.
Das is aber nicht wichtig. Verbraucht dir eh nur Speicher.

Mal paar Beispiel, damit es klar wird:
Notierst du dir eine Auszahlungsanforderung über 0,00€, wenn der User grade keine Anforderung gemacht hat ?

Den einzigen Vorteil, den ich an der "Werber 0"-Variante seh, ist, dass du ohne zusätzlichen Join an alle werberlosen IDs rankommst.
Im Zeitalter von "Ich kaufe Geworbene ein" (wie kann man ein System nur dermaßen ad absurdum führen ? ) könnte es vielleicht von Nutzen sein. Nachteil is halt die Sonderbehandlung, weil du überall auf Werber!=0 checken musst.

Wie ich damals auf einer Loseseite dieses Referalsystem installiert hab, hab ich zusätzlich noch Spalten für prozentuales Refback, heutige Werberlose (jetzt Substantiv ) und die gesamt jemals erhaltenen Werberlose hinzugefügt.
Damit ergibt sich dann automatisch das Feature von mehrstufigen Refback, d.h. der Werber Stufe 2 (also der Werber meines Werbers) kann mir Refback geben.

Würde es jetzt Werber==0 geben, kommt das sehr komisch rüber, wenn ich in meinem UserCP seh:
Zitat:
Du hast insgesamt 1 Werber:
(0) Refback: [0%] - 0 Lose heute, 0 Lose gesamt
Der Nickname fehlt, weil der Join da NULL geliefert hat, der Link auf das Userprofil geht auf ne Fehlerseite, wo nur steht "User nicht gefunden" und auch sonst wundert mich das alles.

Wenn man alles abfängt, ok. Aber es is doch n großer Mehraufwand, weil überall, wo Refberechnungen (Downline, Statistiken, Refback, Refralley, kp, was man sich noch alles einfallen lässt) gemacht werden, der Sonderfall herausgefiltert werden muss.
theHacker ist offline   Mit Zitat antworten
Alt 09.10.2007, 21:08:56   #8
veers
.

ID: 52181
Lose senden

Reg: 27.04.2006
Beiträge: 500
Standard

Für ein Refsystem würde ich Nested Trees empfehlen. Und Spalten zu Nummerieren ist schon mal aus Prinzip schlecht und wird jedem mit Kenntnissen von DB Systemen Übelkeit hervorrufen.
Lanshark - Ein P2P Filesharing-Tool für LANs
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
veers ist offline   Mit Zitat antworten
Antwort

Stichworte
mysql, php, ref, referal, werber

Anzeige


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Newsletter mit Refsystem! pokerface Lose4Scripts 5 23.09.2007 14:29:08
sei-reich.de Der Scriptshop mit Refsystem Alex04 Externe Loseseiten 0 11.07.2007 19:16:19
[s] refsystem DRINGEND RhinoGFX Lose4Scripts 5 13.03.2007 12:28:27
Refsystem Drrichardfahrer Programmierung 15 26.11.2006 15:57:51


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:18:18 Uhr.