quakenet:#php Tutorial

Author: Progman, zuletzt bearbeitet von tittenmaus @ 2004/11/28 14:35:32

Bitte beachten Sie, dass die Tutorialkapitel zusammenhängen. Wenn sie direkt auf ein Kapitel verlinkt wurden müssen Sie gegebenenfalls die vorherigen Kapitel auch lesen. Achten Sie beim lesen darauf, dass Sie kein Kapitel überspringen.

MySQL Querys richtig einrücken

  1. Warum einrücken?
  2. Schlüsselwörter groß schreiben
  3. Schlüsselwörter in MySQL
  4. SELECT-Befehl einrücken
  5. UPDATE-Befehl einrücken
  6. DELETE-Befehl einrücken
  7. INSERT-Befehl einrücken
  8. MySQL-Querys mit einem Semikolon abschließen
  9. SELECT *
  10. MySQL-Querys in PHP

1. Warum einrücken?

Diese Kapitel habe ich nun hier reingeschrieben, damit ich den Leuten in #php und #php.de helfen kann. Denn was da manchmal für MySQL-Querys gesendet wird ist unter aller sau...

Es kann vorkommen, dass ihr einen MySQL-Query sendet und dieser einen Fehler liefert. Dieser Fehler ist nicht unbedingt sofort einsichtig, warum er da ist. Spätestens bei der Fehlermeldung MySQL Error: You have an error near '' at Line 1 steht man auf dem Schlauch. Man kann nicht erkennen, wo jetzt der Fehler ist.

Beim Formartieren des MySQL-Querys ändert sich bei einem Fehler die Zeilenangabe. Dann steht da z.B. ... at Line 5 und könnt da nach eurem Fehler suchen. In PHP rückt ihr ja euren PHP-Code auch ein (hoffe ich zumindest). Ihr schreibt ja nicht den PHP-Code in einer einzigen Zeile, was natürlich möglich wäre. Doch dann habt ihr das selbe Problem wie in MySQL, wenn ein Fehler auftritt. Parse Error: unexcepted T_VARIABLE, excepted T_DOT or T_SEMIKOLON at Line 1 oder so ähnlich. Deshalb sollte man MySQL-Querys entsprechend einrücken. Der Datenbank ist es dabei egal, wenn da Whitespaces wie \n oder Leerzeichen sind.

2. Schlüsselwörter groß schreiben

Es hat sich eingebürgert, dass man Schlüsselwörter wie SELECT und WHERE groß schreibt. Man erkennt dann sofort, was der Query macht, da man sofort zwischen Werten, Tabellennamen, Spaltennamen und Schlüsselwörter unterscheiden kann. Man kann es sich natürlich schwer machen und die Schlüsselwörter nicht komplett groß schreiben.

SeLEct ... FRoM ... wheRe ...;
        

Ich empfehle euch, Schlüsselwörter großzuschreiben.

SELECT ... FROM ... WHERE ...;
        

3. Schlüsselwörter in MySQL

In MySQL gibt es eine Menge von Schlüsselwörter, die man nicht als Spalten benutzen werden. Manchmal sehe ich folgenden Query in den Channels.

SELECT ID,Name,Email,Alter,ICQ FROM users WHERE ID=5;
        

Wenn ihr diesen Query absendet, werdet ihr diese oder eine so ähnlich Fehlermeldung erhalten.

MySQL Error: You have an error near 'Alter, ICQ FROM' near Line 1
        

Wenn ihr MySQL nicht ein wenig kennt werdet ihr den Fehler nie finden. Denn in MySQL ist Alter ein Schlüsselwort. Mit dem ALTER TABLE-Befehl bearbeiten wir die Eigenschaft einer Tabelle. Bei einem SELECT-Befehl ist dieser Befehl fehl am Platz.

Eine Liste der Schlüsselwörter in MySQL, die man nicht als Spalten- und Tabellennamen benutzen darf, findet man im MySQL Manual unter 6.1.7 Is MySQL Picky About Reserved Words?

4. SELECT-Befehl einrücken

Der SELECT-Befehl kann sehr Komplex aufgebaut sein. Jedes Schlüsselwort soll dabei in einer eigenen Zeile stehen. Dadrunter und mit 4 Leerzeichen eingerückt kommen dann die Angaben zu diesem Schlüsselwort. Diese Angaben sollte man entsprechend auch einrücken und übersichtlich schreiben. Hier ein Beispiel wie sowas aussehen könnte.

SELECT
    foo,
    bar
FROM
    tab
WHERE
    ka = '5' AND
    (
        punkte > '0' OR
        fehler < '0'
    )
ORDER BY
    Datum DESC,
    punkte ASC
LIMIT
    10,10;
        

Man kann sofort die jeweiligen Angaben sofort erkennen. Aus was will ich auslesen?, Nach was soll sortiert werden?, Wie lautet die Bedingung?. Welche Angaben man in einem SELECT-Befehl verwenden kann, kann man in der MySQL-Dokumentation nachlesen.

5. UPDATE-Befehl einrücken

Die Einrückung ist so ähnlich wie bei dem SELECT-Befehl. Dies könnte so aussehen.

UPDATE
    tab
SET
    punkte = '0',
    Datum = NOW()
WHERE
    punkte < '0' OR
    punkte > '1000';
        

6. DELETE-Befehl einrücken

Da der DELETE-Befehl nur etwa so viele Angaben hat wie der UDPATE-Befehl ist die Formartierung eines DELETE-Befehls sehr einfach.

DELETE FROM
    tab
WHERE
    wir < sie;
        

7. INSERT-Befehl einrücken

Einen INSERT-Befehl richtig einrücken ist schwer, denn ein INSERT-Befehl kann unterschiedlich aufgebaut sein. Die meißten kennen die Form mit VALUES und sollten den Query in etwa so formartieren.

INSERT INTO
    news(Inhalt, Datum, Poster)
VALUES
    ('Ein verdammt toller text',
     NOW(),
     '4');
        

Diesen Query kann man aber auch anders formartieren.

INSERT INTO news
    (Inhalt,
     Datum,
     Poster)
VALUES
    ('Ein verdammt toller text',
     NOW(),
     '4');
        

Hier kann man gucken, ob man genausoviele Spalten wie Werte angegeben hat. Wenn nicht bekommt man eine Fehlermeldung wie MySQL Error: Value Columns doesn't match Table Columns.

Der INSERT Befehl kann auch mit einer SET-Angabe benutz werden, die dann wie folgt aussieht.

INSERT INTO
    tab
SET
    Name = 'foo',
    Email = 'bar';
        

Hier hat man eine direkte Zuordnung von Werten und Spalten. Aber diese einfache Methode um einen neuen Datensatz hinzuzufügen habe ich nicht durchgenommen, weil man den Aufbau sonst mit einem UPDATE-Befehl verwechseln könnte. Denn INSERT-Befehle können z.B. kein WHERE oder LIMIT enthalten, UPDATE-Befehle hingegen schon. Man würde sich da leicht vertun und ggf. solche Querys zusammenreimen.

INSERT INTO
    users
SET
    foo = 'bar'
WHERE
    ID != '5';
        

Man dachte hier vielleicht, das man einen Datensatz hinzufügt, wenn es keinen Datensatz mit der ID 5 gibt. Sowas hab ich alles schon gesehen...

8. MySQL-Querys mit einem Semikolon abschließen

Jeder MySQL-Befehl muss mit einem Semikolon abgeschlossen werden. Anhand des Semikolons kann MySQL mehrere Querys unterscheiden. In PHP sendet man ja Query an die Datenbank mit mysql_query. Bei dieser Funktion darf man aber das Semikolon weglassen. Das liegt daran, dass mysql_query er nur ein Query ausführt, selbst wenn dieser Funktion 2 oder mehrere MySQL-Querys mit Semikolon getrennt übergeben wurden. Dies heißt jetzt nicht, dass ihr nun immer die Semikolons weglassen könnt. Ihr solltet euch daran gewöhnen, dass MySQL-Querys mit einem Semikolon abgeschlossen werden. Denn es kann mal sein, dass ihr direkt an der MySQL-Datenbank mit dem Programm mysql arbeitet. Da muss jeder Befehl mit Semikolon abgeschlossen werdet. Hättet ihr nun gelernt, dass man bei MySQL keine Semikolons braucht, so würdet ihr mit dem Programm mysql nur Probleme kriegen und euch fragen, warum der Query nicht ausgeführt wird. Ich empfehle euch daran zu denken, dass man MySQL-Querys, auch in PHP, mit einem Semikolon beendet.

9. SELECT *

Von anderen Tutorials oder Hilfeseiten kennt man den Ausdruck SELECT *. Dies sollte man in seinen Anwendungen nicht benutzen. Warum wird in der php-FAQ unter 15.14. Warum soll ich nicht SELECT * schreiben? erklärt.

10. MySQL-Querys in PHP

In PHP sollte man, wegen der Übersicht, den Query in einer extra Variablen speichern. Dabei sollte man, wie oben erklärt, den Query über mehrere Zeilen schreiben. Dabei sollte man den Query auf das erste Schlüsselwort einrücken.

<?php
    $sql
= "SELECT
    foo,
    bar,
FROM
    tab;"
;
?>

So ist es falsch.

<?php
    $sql
= "SELECT
                foo,
                bar,
            FROM
                tab;"
;
?>

So ist es richtig. Den Query senden wir dann wie üblich mit mysql_query mit $sql als Parameter an die Datenbank ab. Der Vorteil des Zwischenspeichers ist, dass man bei einem Fehler noch den Query ausgeben kann.

<?php
    $result
= mysql_query($sql) OR die("'".$sql."' : ".mysql_error());
?>

In manchen Situationen will man nur bestimmte Daten auslesen. Diese werden üblicherweise von einem Benutzer mittels eines Formulares gewählt. Der Benutzer muss aber nicht das fertige Formular benutzen sondern kann sich ein eigenes Schreiben. Dies macht er mit den Ziel die Datenbank zu hacken. Und wie?

Nehmen wir an wie haben folgenden Query.

SELECT
    password
FROM
    users
WHERE
    ID = '".$_POST['ID']."';
        

In dem Formular würde man normalerweise die ID eingeben, z.B. 5. Doch was ist wenn man 0' OR 1 OR 'foo' = ' eingibt. Dann sieht der zusammengesetze Query so aus.

SELECT
    password
FROM
    users
WHERE
    ID = '0' OR 1 OR 'foo' = '';
        

Und eine OR-Verknüpfung wo eine 1 steht ist immer true/wahr. Das heißt, dass hier jeder Datensatz ausgelesen wird. Der Hacker bekommt nun von allen Usern das Password angezeigt.

Deshalb sollte man immer die Eingaben prüfen. Man kann aber auch einen anderen Trick benutzten. Die Funktion sprintf liefert einen Übergebene String, der Platzhalter hatte, wieder zurück. Der Funktion muss man dann für die Platzhalter die Werte übergeben. Dies sieht z.B. so aus.

<?php
    $sql
= sprintf("SELECT
                        foo
                    FROM
                        tab
                    WHERE
                        ID = '%u';"
, $_POST['ID']);
?>

Egal was in $_POST['ID'] steht, dieser Wert wird in durch den Platzhalter in einer Zahl umgewandelt. Der Benutzer kann nun nichtmehr OR Verknüpfungen hinzufügen. Es empfielt sich deshalb die Dokumentation von sprintf durchzulesen.

Fragen zum aktuellen Thema

  1. Warum soll ich einrücken?
Warum soll ich einrücken?

Einrücken erleichtet das Lesen von MySQL-Querys. Man sieht sofort was zu was gehört. Zusätzlich wird bei einem Fehler die fehlerhafte Zeile mit ausgegeben. Würden wir alles in einer Zeile schreiben, so würde da "... at Line 1" stehen. Dadurch werden wir ja nicht grad schlauer.

Nach oben