quakenet:#php Tutorial

Author: Progman, zuletzt bearbeitet von progman @ 2005/03/06 16:17:33

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.

Zu einer MySQL-Datenbank connecten

  1. Verbindung aufbauen
  2. Datenbank auswählen
  3. mysql_error/mysql_errno
  4. Optimieren des Login-Scripts
  5. Die Power von OR und AND

1. Verbindung aufbauen

Wenn wir auf eine MySQL-Datenbank zugreifen wollen, müssen wir erstmal eine Verbindung mit der Datenbank aufbauen. Diese Verbindung bleibt im Normalfall bis zum Ende des Scriptes bestehen. Danach wird die Verbindung wieder geschlossen.

Um eine Verbindung mit einer Datenbank aufzunehmen benutzt man die Funktion mysql_connect.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden
    
    
$db_link = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS);
?>

Mit den 3 Parametern geben wir mysql_connect an, zu welcher Datenbank, mit welchem User und mit welchem Password er sich einloggen soll. Der Rückgabewert von mysql_connect ist entweder FALSE, wenn keine Verbindung aufgebaut werden konnte, oder ist sowas wie eine Verknüpfung zur Datenbank. Anderen Funktionen kann man dann diesen Link übergeben, falls diese ihn brauchen. Die Variable, die den Rückgabewert von mysql_connect enthält, kann man mit einer einfachen if-Abfrage prüfen.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
$db_link = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS);
    
    if(
$db_link) {
        echo
"Verbindung wurde aufgebaut<br />\n";
        echo
"In der Variable steht folgendes: ".$db_link;
    } else {
        echo
"Es konnte keine Verbindung aufgebaut werden";
    }
?>

Wenn wir die Variable ausgeben, erscheint dann sowas wie Resource id #1. Das ist nur die Ausgabe der Variable als String, bedingt durch das echo. Intern wird die Variable anders gespeichert.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
$db_link = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS);

    if(
$db_link) {
        echo
"Verbindung wurde aufgebaut<br />\n";
        echo
"<pre>\n";
        
var_dump($db_link);
        echo
"</pre>\n";
    } else {
        echo
"Es konnte keine Verbindung aufgebaut werden";
    }
?>

Hier erscheind dann sowas wie resource(1) of type (mysql link). Hier sieht man das die Variable ein MySQL Link auf eine Datenbank ist. Und das stimmt ja auch, wir haben ja den Rückgabewert von mysql_connect in die Variable gespeichert.

Wir geben jetzt mal ganz bewusst falsche Logindaten an

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
$db_link = mysql_connect(MYSQL_HOST, MYSQL_USER, "iuerbnviuebv");

    if(
$db_link) {
        echo
"Verbindung wurde aufgebaut<br />\n";
        echo
"<pre>\n";
        
var_dump($db_link);
        echo
"</pre>\n";
    } else {
        echo
"Es konnte keine Verbindung aufgebaut werden";
    }
?>

Ausgabe ist wie folgt.

Warning: Access denied for user: 'progman@localhost' ...

Warning: MySQL Connection Failed: Access denied for ...
Es konnte keine Verbindung aufgebaut werden
        

Hier sehen wir einmal das unser else-Teil ausgeführt wurde. Was uns aber mehr stört, als das, dass wir keine Verbindung aufbauen konnten, sind die zusätzlichen Fehlermeldungen. Diese Fehlermeldungen wurden von der Funktion mysql_connect erzeugt. Diese Fehlermeldungen sehen aber nicht so schön aus. Und in der zukünftigen Homepage sehen sie noch schlechter aus, weil die absolut nicht ins design passen.

In PHP haben wir die Möglichkeit Fehlermeldungen von Funktionen und Ausdrücken zu unterdrücken. Dies macht man, indem man vor der Funktion oder dem Ausdruck ein @ schreibt.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
$db_link = @mysql_connect(MYSQL_HOST, MYSQL_USER, "iuerbnviuebv");
    
//         ^-- Hier ist das @

    
if($db_link) {
        echo
"Verbindung wurde aufgebaut<br />\n";
        echo
"<pre>\n";
        
var_dump($db_link);
        echo
"</pre>\n";
    } else {
        echo
"Es konnte keine Verbindung aufgebaut werden";
    }
?>

Wenn wir jetzt die Seite aufrufen, wird nur unser else-Teil ausgeführt. Die Fehlermeldung, die eigentlich kommen sollte, wird nicht mehr angezeigt. Dies heißt aber auch, dass wir selber dafür zuständig sind eine entsprechende Fehlermeldung auszugeben. Es sieht nunmal besser aus wenn da steht Die Verbindung zur MySQL-Datenbank konnte nicht aufgebaut werden. Bitte versuchen sie es in 10 min wieder als das da eine PHP Fehlermeldung wie Warning: Access denied for user: 'progman@localhost' (Using password: YES) in /.../index.php on line 7 steht. Diese @ ist natürlich keine Einladung dass wir vor allen Funktionen ein @ schreiben. Nach dem Motto: "Scheisse, schon wieder eine Fehlermeldung und ich weiß nicht warum. Ach mach ich einfach ein @ davor, dann ist sie ja weg". Wenn wir das @ benutzen dann müssen wir die Fehlermeldung z.B. mit einer If-Abfrage selber abfangen.

2. Datenbank auswählen

Wenn wir nun unsere Verbindung zur Datenbank aufgebaut haben, so müssen wir als nächstes die Datenbank wählen in der wir arbeiten wollen. Dies machen wir mit der Funktion mysql_select_db.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
$db_link = @mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS);

    if(
$db_link) {
        echo
"Verbindung wurde aufgebaut<br />\n";

        if(
mysql_select_db(MYSQL_DATABASE, $db_link)) {
            echo
"Die Datenbank ".MYSQL_DATABASE." wurde ausgewählt";
        } else {
            echo
"Datenbank ".MYSQL_DATABASE." wurde nicht gefunden";
        }
    } else {
        echo
"Es konnte keine Verbindung aufgebaut werden";
    }
?>

Die Funktion mysql_select_db liefert TRUE wenn die Datenbank ausgewählt werden konnte und FALSE wenn nicht. Der Parameter $db_link ist optional d.h. dieser Parameter kann weggelassen werden. Wenn der Parameter weggelassen wird, so nimmt PHP die grad offene Verbindung. Da wir hier mit nur einer MySQL-Datenbank arbeiten können wir diesen Parameter weglassen. Würden wir aber mit mehreren MySQL-Datenbanken gleichzeitig in einem Script arbeiten müssen wir immer die Link-ID übergeben, damit PHP weiß, wo er jetzt was machen soll. Es ist aber sehr unwahrscheinlich das man in einem Script mit 2 MySQL-Datenbanken hantiert.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
$db_link = @mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS);

    if(
$db_link) {
        echo
"Verbindung wurde aufgebaut<br />\n";

        if(
mysql_select_db(MYSQL_DATABASE)) {
            echo
"Die Datenbank ".MYSQL_DATABASE." wurde ausgewählt";

            
// Hier kann man jetzt MySQL-Querys senden
        
} else {
            echo
"Datenbank ".MYSQL_DATABASE." wurde nicht gefunden";
        }
    } else {
        echo
"Es konnte keine Verbindung aufgebaut werden";
    }
?>

An der Stelle wo jetzt der Kommentar steht schreibt man dann die MySQL-Funktionen hin. Zu diesem Zeitpunkt sind wir komplett zur Datenbank connected und haben die Datenbank ausgewählt mit der wir arbeiten wollen.

3. mysql_error/mysql_errno

Es kann vorkommen, das ein MySQL-Query ein Fehler hat, dieser aber nicht ausgegeben wird. Die Funktionen mysql_error und mysql_errno dienen dazu sich die Fehlermeldung anzeigen zu lassen. mysql_error liefert eine Fehlermeldung zurück, mysql_errno hingegen nur die Fehlernummer. Diese Funktionen (vorallem die erste der beiden) braucht man z.B. für die Funktion mysql_select_db. Wenn mysql_select_db false zurückliefert konnte die angegebene Datenbank nicht ausgewählt werden. Aber vielleicht möchten wir ja wissen, warum MySQL die Datenbank nicht auswählen konnte. Das können wir einfach erfahren indem wir den Rückgabewert von mysql_error, und vielleicht auch noch von mysql_errno, ausgeben.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
$db_link = @mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS);

    if(
$db_link) {
        echo
"Verbindung wurde aufgebaut<br />\n";

        if(
mysql_select_db("owrvworvn")) { // diese Datenbank gibt es nicht
            
echo("Die Datenbank wurde ausgewählt");

            
// Hier kann man jetzt MySQL-Querys senden
        
} else {
            echo
"Konnte Datenbank nicht benutzen.<br />\n";
            echo
"Der Grund dafür: ".mysql_error()."\n";
        }
    } else {
        echo
"Es konnte keine Verbindung aufgebaut werden";
    }
?>

Die Fehlermeldung kann jetzt überall anders aussehen. So sah sie bei mir aus.

Access denied for user: '@localhost' to database 'test5'
        

Diese Funktionen sind wichtig für die weitere Benutzung von MySQL.

4. Optimieren des Login-Scripts

Wir haben jetzt ca. 15 Zeilen gebraucht nur um uns bei MySQL gültig einzuloggen. Doch eigentlich braucht man nur 2 Zeilen, wenn man weiß wie...

Hier ist unser Script

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
$db_link = @mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS);

    if(
$db_link) {
        echo
"Verbindung wurde aufgebaut<br />\n";

        if(
mysql_select_db(MYSQL_DATABASE)) { // diese Datenbank gibt es nicht
            
echo("Die Datenbank wurde ausgewählt");

            
// Hier kann man jetzt MySQL-Querys senden
        
} else {
            echo
"Konnte Datenbank nicht benutzen.<br />\n";
            echo
"Der Grund dafür: ".mysql_error()."\n";
        }
    } else {
        echo
"Es konnte keine Verbindung aufgebaut werden";
    }
?>

Wir haben den Rückgabewert von mysql_connect in eine Variable gespeichert und diese mit einer If-Abfrage auf true bzw. false untersucht. Da wir aber die Variable in unserem Script nicht braucht können wir uns den Zwischenschritt über die Variable schenken.

<?php
    error_reporting
(E_ALL);

    include(
"inc/config.php");
    
// Konfigurationsdatei laden

    
if(@mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS))
    {
        echo
"Verbindung wurde aufgebaut<br />\n";

        if(
mysql_select_db(MYSQL_DATABASE))
        {
            echo
"Die Datenbank wurde ausgewählt";

            
// Hier kann man jetzt MySQL-Querys senden
        
}
        else
        {
            echo
"Konnte Datenbank nicht benutzen.<br />\n";
            echo
"Der Grund dafür: ".mysql_error()."\n";
        }
    }
    else
    {
        echo
"Es konnte keine Verbindung aufgebaut werden";
    }
?>

Jetzt müssen wir die If-Abfragen umstrukturieren. Denn das was wir jetzt hier gemacht haben ist eigentlich scheisse. Nehmen wir an wir rufen noch 10 MySQL-Funktionen auf. Jede Funktion muss mit einer If-Abfrage untersucht werden. Dies sähe dann so aus:

<?php
    
if(mysql_xyz()) {
        
was_anderes();
        if(
mysql_foobar()) {
            
foobar();
            
xyz();
            if(
mysql_abc()) {
                
// usw.
            
} else {
                echo
"ging nicht";
            }
        } else {
            echo
"ging nicht";
        }
    } else {
        echo
"ging nicht";
    }
?>

Dieses Ineinanderschachteln von If-Abfrage sollte man möglichs vermeiden oder nur auf kleine Ebenen wie 4-5 beschränken. Deswegen müssen wir uns was einfallen lassen wie wir das umschreiben können.

Das erste was wir machen ist, dass wir die If-Abfrage umdrehen. Einmal die If-Bedingung negieren und else und if-Teil miteinander tauschen.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
if(!@mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS)) {
        echo
"Es konnte keine Verbindung aufgebaut werden";
    } else {
        echo
"Verbindung wurde aufgebaut<br />\n";

        if(!
mysql_select_db(MYSQL_DATABASE)) {
            echo
"Konnte Datenbank nicht benutzen.<br />\n";
            echo
"Der Grund dafür: ".mysql_error()."\n";
        } else {
            echo
"Die Datenbank wurde ausgewählt";
            
            
// Hier kann man jetzt MySQL-Querys senden
        
}
    }
?>

Jetzt steht die Fehlermeldung oben und der weitere Code unten. Jetzt müssen wir die If-Else-Anweisungen in eine reine If-Anweisung umformen.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
if(!@mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS)) {
        echo
"Es konnte keine Verbindung aufgebaut werden";
    }
    
    echo
"Verbindung wurde aufgebaut<br />\n";

    if(!
mysql_select_db(MYSQL_DATABASE)) {
        echo
"Konnte Datenbank nicht benutzen.<br />\n";
        echo
"Der Grund dafür: ".mysql_error()."\n";
    }

    echo
"Die Datenbank wurde ausgewählt";

    
// Hier kann man jetzt MySQL-Querys senden
?>

So sieht es schon recht gut aus. Aber bei einem Fehler wird trotzdem weiterverarbeitet. Deswegen müssen wir PHP veranlassen das Script nach dem else-Teil zu beenden. Dies geht mit der Funktion die bzw. exit.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
if(!@mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS)) {
        echo(
"Es konnte keine Verbindung aufgebaut werden");
        die();
// Script beenden
    
}

    echo
"Verbindung wurde aufgebaut<br />\n";

    if(!
mysql_select_db(MYSQL_DATABASE)) {
        echo
"Konnte Datenbank nicht benutzen.<br />\n";
        echo
"Der Grund dafür: ".mysql_error()."\n";
        die();
// Script beenden
    
}

    echo
"Die Datenbank wurde ausgewählt";

    
// Hier kann man jetzt MySQL-Querys senden
?>

Der Funktion die bzw. exit kann man einen String übergeben. Dieser String wird dann vorm Beenden des Scripts noch ausgegeben. Ist also wie ein eingebauter echo-Befehl.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
if(!@mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS)) {
        die(
"Es konnte keine Verbindung aufgebaut werden");
    }

    echo
"Verbindung wurde aufgebaut<br />\n";

    if(!
mysql_select_db(MYSQL_DATABASE)) {
        die(
"Konnte Datenbank nicht benutzen, Fehlermeldung: ".mysql_error());
    }

    echo
"Die Datenbank wurde ausgewählt";

    
// Hier kann man jetzt MySQL-Querys senden
?>

Somit haben wir einmal die verschachtelten If-Abfragen beseitig und die If-Abfragen selber verkleinert. Unten kann nun der weiter Programmcode folgen.

5. Die Power von OR und AND

"Was haben denn jetzt die Logischen Verknüpfungen OR und AND mit MySQL zu tun?". Die logischen Verknüpfungen OR und AND werden in PHP besonders abgearbeitet. Man kann sie zum Beispiel bei mysql_connect und mysql_select_db verwenden.

Wenn PHP ein Ausdruck wie false AND true sieht, so wandelt PHP diesen Ausdruck in false um, haben wir ja kennengelernt. PHP versucht diesen Ausdruck so schnell wie möglich abzuarbeiten. Dabei guckt er sich den Ausdruck genau an und überlegt sich wann er weiter gucken soll und wann es sinnlos ist sich noch den Rest der Bedingung anzugucken. In diesem Fall guckt er sich erstmal den linken Ausdruck vom AND an. Dort steht ein false. Das was hinter dem AND steht ist eigentlich egal, denn PHP weiß jetzt schon, dass die Bedingung auf jedenfall false ergeben wird.

Statt solche Werte wie true und false können dort auch Funktionen stehen.

<?php
    xyz
() AND foobar();
?>

Hierbei ruft PHP die Funktion xyz() auf und guckt sich den Rückgabewert an. Wenn dieser false ist, dann braucht er sich den rechten Teil von AND garnicht angucken. Das heißt, dass die Funktion foobar() garnicht aufgerufen wird. Denn PHP weiß ja schon das Ergebnis der AND-Verknüpfung. Dieses Feature kann man auch bei OR benutzen und wird auch häufiger benutzt.

<?php
    xyz
() OR foobar();
?>

Hier versucht PHP auch wieder nur so wenig wie Möglich auszuführen um das Ergebnis zu erfahren. Wenn die Funktion xyz() nun true zurückliefert, so braucht PHP den rechten Teil nicht mehr zu prüfen, denn das Ergebnis steht ja schon fest. Wäre aber der Rückgabewert von xyz() nun false, dann weiß PHP das Ergebnis noch nicht. Er muss nun weiter die Verknüpfung(en) durchgucken bis er das Ergebnis eindeutig sagen kann. Dieses Wissen können wir nun für unser MySQL-Loginteil benutzen.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
@mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS) OR
        die(
"Es konnte keine Verbindung aufgebaut werden");

    echo
"Verbindung wurde aufgebaut<br />\n";

    
mysql_select_db(MYSQL_DATABASE) OR
       die(
"Konnte Datenbank nicht benutzen, Fehlermeldung: ".mysql_error());

    
/*
     * Eigentlich gehört die die() Funktion optisch hinter dem OR, aber
     * dann würde die Tutorialseite unnötig breit werden. In eurem
     * Projekt solltet ihr das die() hinter dem OR schreiben um es
     * übersichtlicher zu haben.
     *
     * p.s.: Die * sind eigentlich keine Bestandteile
     *       für ein Mehrzeilenkommentar, aber so
     *       kann man einfacher ein Mehrzeiligen
     *       Kommentar entdecken.
     */

    
echo "Die Datenbank wurde ausgewählt";

    
// Hier kann man jetzt MySQL-Querys senden
?>

Hier wird zuerst versucht eine Verbindung aufgebaut, wie wir es ja kennen. Da diese Funktion entweder false oder eine Resource-ID (also etwas, was true ergibt) zurückliefert, wird der andere Teil von OR nur dann ausgeführt, wenn die Verbindung nicht aufgebaut werden konnte. Und das heißt: Script mit einer Fehlermeldung beenden. Im richtigen Script nimmt man noch die diversen echo-Befehle raus und schreibt die die-Meldungen etwas um.

<?php
    error_reporting
(E_ALL);

    include
'inc/config.php';
    
// Konfigurationsdatei laden

    
@mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS) OR
        die(
"Keine Verbindung zur Datenbank. Fehlermeldung:".mysql_error());
    
mysql_select_db(MYSQL_DATABASE) OR
        die(
"Konnte Datenbank nicht benutzen, Fehlermeldung: ".mysql_error());

    
// Hier kann man jetzt MySQL-Querys senden
?>

Und das ist alles, was man zum Connecten braucht. Dadrunter kommen nun die MySQL-Befehle die man an eine Datenbank sendet bzw. ausließt. Statt die() kann da natürlich eine andere Funktion stehen. Z.B. eine Funktion die die Fehlermeldung schön formartiert zum Client schickt.

Fragen zum aktuellen Thema

  1. Mit welchen Funktionen baue ich eine Verbindung zum MySQL-Server auf?
  2. Was ist das besondere an AND und OR?
Mit welchen Funktionen baue ich eine Verbindung zum MySQL-Server auf?

Mit der Funktion mysql_connect wird eine Verbindung zum MySQL-Server aufgebaut. Wenn man mit mehreren Datenbanken in einem Script hantiert sollte man die Resource-ID, die diese Funktione zurückliefert, in eine Variable speichern.

Was ist das besondere an AND und OR?

Diese Verknüpfungsoperatoren werden nur so weit ausgewertet wie nötig. Wenn das Ergebnis der Verknüpfung schon vor der ganzen Auswertung feststeht, so wird die Auswertung sofort beendet und ggf. das Ergebnis in eine Variable gespeichert oder mit einer if-Abfrage verarbeitet.

Nach oben