Haumis wbb hilfe (http://haumis-wbb-hilfe.de/wbb2/index.php)
- ...:::Trainingscenter-wbb2:::... (http://haumis-wbb-hilfe.de/wbb2/board.php?boardid=75)
-- Allgemeines zur wbb-Software (http://haumis-wbb-hilfe.de/wbb2/board.php?boardid=77)
--- Tutorial zum Thema Datenbankabfragen (http://haumis-wbb-hilfe.de/wbb2/thread.php?threadid=1702)


Geschrieben von Steinadler am 14.10.2011 um 17:41:

  Tutorial zum Thema Datenbankabfragen

Hier jetzt mal ein kleines Tutorial, damit man die Datenbankabfragen in den php's besser versteht, und somit unnötige Fehler vermeiden kann.

Betrachten wir uns jetzt mal eine Datenbankabfrage etwas genauer!

Beispiel aus der original index.php eines wbbLite:

In der Regel sieht eine x-beliebige Datenbankabfrage so aus: (Hier jetzt die Abfrage für die Useronlinespalte auf der Indexseite)

php:
1:
$result $db->query("SELECT bb".$n."_sessions.userid, username, groupid, invisible FROM bb".$n."_sessions LEFT JOIN bb".$n."_users USING (userid) WHERE bb".$n."_sessions.lastactivity >= '".(time()-60*$useronlinetimeout)."' ORDER BY username ASC");


Die Abfrage fängt (fast) immer mit:
php:
1:
$result $db->query


D.h. frei übersetzt: Das Ergebnis = Deine Datenbank wird abgefragt

php:
1:
"SELECT bb".$n."_sessions.


Selektiere (hole mir das Ergebnis) aus der Boardnummer ($n) Tabelle sessions.
Im php-Admin heisst es dann: bbx_sessions, wobei das x für Eure verwendete Boardnummer steht.
Das könnt Ihr sehr oft in den Einbauanleitungen der diversen Hacks lesen.

php:
1:
useridusernamegroupidinvisible


hole mir die:
userid = Mitgliedsnummer im Board
username = den Namen, mit dem man sich im Board registriert hat
groupid = die Gruppe, der man angehört(kann Admin, Mod,User oder
sonst eine angelegte Gruppe in Eurem Forum sein)
invisible = schau nach, ob man sich im Profil auf unsichtbar gestellt hat

php:
1:
FROM bb".$n."_sessions


aus der Tabelle bbx_sessions

php:
1:
LEFT JOIN bb".$n."_users USING (userid)


Mit der Operation LEFT JOIN ist der vollständige Einschluss von Daten einer Tabelle gemeint, im Bezug auf die Verbindung zu einer anderen Tabelle.
In unserem Fall sollen also alle Daten aus der Tabelle bbx_users geholt werden zusätzlich der Daten aus der Tabelle bbx_sessions.

php:
1:
WHERE bb".$n."_sessions.lastactivity >= '".(time()-60*$useronlinetimeout)."'


Mit WHERE kann das Ergebnis der SELECT-Anweisung eingeschränkt werden. Die gewählte Bedingung muss der FROM-Klausel folgen.
In unserem Fall also die letzte Aktivität aus der Tabelle sessions.
Der Rest ('".(time()-60*$useronlinetimeout)."') soll hier jetzt vorerst keine Rolle spielen.

php:
1:
ORDER BY username ASC


ORDER BY steht für die Reihenfolge der Ausgabe.
ASC für aufsteigend......DESC wäre absteigend.
Hier in unserem Beispiel sollen also die Namen nach Alphabet aufsteigend aufgelistet werden.

Zwischenergebnis:

An diesem Beispiel sind einige grundlegende Bedingungen zu erkennen. Nur SELECT und FROM sind erforderlich, was es sonst noch alles an möglichen Befehlen gibt (WHERE, ORDER BY usw.) ist optional.
Am Ende der Anweisung steht ein Semikolon ;.
Jede Anweisung wird mit einem Semikolon abgeschlossen, das ist beispielsweise bei PHP auch der Fall.

Wir können also jetzt hergehen und unsere Abfrage etwas aufgeräumter darstellen:

php:
1:
2:
3:
4:
5:
6:
$result $db->query("SELECT bb".$n."_sessions.
userid, username, groupid, invisible 
FROM bb".$n."_sessions 
LEFT JOIN bb".$n."_users USING (userid) 
WHERE bb".$n."_sessions.lastactivity >= '".(time()-60*$useronlinetimeout)."' 
ORDER BY username ASC");


Das hat den Vorteil, das die einzelnen Abschnitte einer Datenbankabfrage für anstehende Änderungen oder Erweiterungen z.B. beim Hackeinbau besser sichtbar, und damit leichter zu finden sind.
Für mich macht das ganz besonders Sinn bei besonders langen Abfragen, wie Sie z.B. in der acp/users.php oder acp/group.php zu finden sind.
In diesen Dateien werden sehr oft, gerade bei Änfängern Fehler gemacht.

Kommen wir jetzt zum Kapitel der unterschiedlichen MySQL Fehlermeldungen:

Ich möchte hier anhand einiger Beispiele Fehlermeldung auflisten, und aufzeigen, wie diese zu Stande kommen.

Ausgangspunkt soll wieder unsere bekannte Datenbankabfrage aus der index.php sein.

1.Fehler

php:
1:
2:
3:
4:
5:
6:
$result $db->query("SELECT bb".$n."_sessions.
userid, username, groupid,, invisible 
FROM bb".$n."_sessions 
LEFT JOIN bb".$n."_users USING (userid) 
WHERE bb".$n."_sessions.lastactivity >= '".(time()-60*$useronlinetimeout)."' 
ORDER BY username ASC")


Fehlermeldung:

SQL-DATABASE ERROR

Database error in WoltLab Burning Board: Invalid SQL: SELECT u.*, userid, u.username, regdate, u.groupid,, u.invisible, avatarid, userposts, u.useronlinemarking AS marking, g.useronlinemarking FROM bb1_sessions LEFT JOIN bb1_users u USING(userid) LEFT JOIN bb1_groups g ON (g.groupid=u.groupid) WHERE bb1_sessions.lastactivity >= '1290973052' ORDER BY username ASC
mysql error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' u.invisible, avatarid, userposts, u.useronlinemarking AS marking, g.user' at line 5
mysql error number: 1064
Date: 28.11.2010 @ 21:37
Script: /index.php?sid=
Referer: http://xxxxxxxxxx.de/editpost.php?postid=213&sid=

Bums.....da haben wir den Salat, und direkt Stress weil man vor einem vermeindlich unüberwindbarem Hindernis steht.

Betrachten wir uns jetzt die Fehlermeldung mal etwas genauer:

Solche Meldungen kann man vereinfacht in 3 Teile splitten:
1.Teil

php:
1:
Database error in WoltLab Burning BoardInvalid SQLSELECT u.*, useridu.usernameregdateu.groupid,, u.invisibleavatariduserpostsu.useronlinemarking AS markingg.useronlinemarking FROM bb1_sessions LEFT JOIN bb1_users u USING(useridLEFT JOIN bb1_groups g ON (g.groupid=u.groupidWHERE bb1_sessions.lastactivity >= '1290973052' ORDER BY username ASC


In diesem Teil wird der Datenbankbefehl quasi komplett aufgelistet, wie er in der entsprechenden php zu sehen ist.

php:
1:
mysql errorYou have an error in your SQL syntaxcheck the manual that corresponds to your MySQL server version for the right syntax to use near ' u.invisible, avatarid, userposts, u.useronlinemarking AS marking, g.user' at line 5


Das ist der Teil der Datenbankabfrage, die nicht mehr zu lesen(zu verarbeiten) ist, weil vorher was faul ist!

php:
1:
Script: /index.php?sid=


Das ist die php, in der der Fehler verursacht wird, also hier die index.php

Wir haben also festgestellt, das der Fehler vor dem invisible sein muss, da die Meldung das ja beanstandet.

Wie man unschwer sehen kann habe ich einfach ein Komma zuviel in die Abfrage eingebaut.

diese Stelle:

php:
1:
useridusernamegroupid,, invisible

korrekt sieht das natürlich so aus:

php:
1:
useridusernamegroupidinvisible


Das ist ein ganz typischer Einbaufehler, wie es beim Hackeinbau schon zigmal vorgekommen ist.
Ein Komma zuviel oder zu wenig reicht aus um ein Forum komplett lahmzulegen.

Fortsetzung folgt!!



Geschrieben von haumi am 14.10.2011 um 19:54:

 

Tolle Ausarbeitung Steinadler st12 st12 st12
Ergänzend soll man noch erwähnen, das die Verknüpfung
der beiden Tabellen mit dem Schlüsselwort USING und dem Tabellenfeld "userid"
hergestelt wird.
(Schlüssel und Fremdschlüssel.)

Hier zeigt sich die Stärke von php, was sehr viele Schnittstellen zu MySQL beinhaltet.

LG
haumi


Forensoftware: Burning Board 2.3.6, entwickelt von WoltLab GmbH