Das PHP-Skript

Es folgt nun das Skript, welches die angesprochenen Aufgaben erfüllt, wobei die einzelnen Abschnitte dabei kurz erklärt werden. Die für die Anbindung an die Datenbank nötigen Teile sind in den Funktionen list_links, update_link, drop_link, insert_link und read_link zu finden. Der Rest beschäftigt sich mit Plausibilitätskontrollen, der Steuerungslogik sowie der Ausgabe von Daten und Formularen. Wie Sie HTML-Code und PHP miteinander kombinieren können wird unter PHP Script und HTML näher erklärt.

Im Ersten Abschnitt werden zunächst die Zugangsdaten, die für den Zugriff auf die Datenbank nötig sind, initialisiert. Diese Daten werden von den Funktionen, welche mit der Datenbank kommunizieren, genutzt. Das Beispiel nutzt eine auf dem lokalen Rechner (localhost) laufende MySQL-Datenbank mit dem Namen test. Der zu konnektierende Benutzer hat den Namen test und benötigt kein Passwort. Die darauf folgende Funktion Eingabe_plausi prüft die vom Formular per POST übergebenen Eingabedaten auf Korrektheit. Geprüft werden die Gültigkeit der eingegebenen URL – diese muss mit "http://" beginnen und einen gültigen Domain-Namen enthalten – und ob ein Titel für den Link angegeben wurde. Wurden die Daten korrekt eingegeben, so liefert die Funktion TRUE.

<?php
# Verbindungsdaten fuer den Zugriff auf die Datenbank
$db_server = "localhost";
$db_name = "test";
$db_user = "test";
$db_password = "";

# Prueft, ob die Eingabedaten korrekt sind und liefert true,
# wenn die Daten korrekt sind
function Eingabe_plausi()
{
    $retval = TRUE;

    if (!isset ($_POST['url']))
        return FALSE;
    # Titel vergeben?
    if (isset ($_POST['title']) && $_POST['title'] == "")
    {
        echo "\t\tEingabefehler: Der Titel f&uuml;r den Link fehlt!<br>\n";
        $retval = FALSE;
    }
    # gueltige URL?
    if (isset ($_POST['url']) &&
        !ereg ("^((http\://)(www.)?((([0-9a-z][0-9a-z-]+\.)+)([a-z]{2,3})))", $_POST['url']))
    {
        echo "\t\tEingabefehler: Keine g&uuml;ltige URL!"
         . "(muss mit 'http://' beginnen und einen g&uuml;ltigen"
         . " Domain-Namen enthalten!)<br>\n";
        $retval = FALSE;
    }

    return $retval;
}

Im nächsten Code-Abschnitt steht die Funktion list_links. Diese Funktion liest die Link-Daten aus der Datenbank ein und gibt sie in Form einer HTML-Tabelle aus. Darüber hinaus werden je Link-Datensatz – pro Tabellenzeile – Links zum Ändern und Löschen des jeweiligen Datensatzes ausgegeben. Die Erste Zeile in der Funktion importiert die im letzten Code-Abschnitt definierten globalen Variablen, die zum Zugriff auf die Datenbank benötigt werden und macht sie innerhalb der Funktion nutzbar (was auch in den anderen Funktionen passiert).

Mit der MySQL-Funktion mysql_connect wird als erstes eine Verbindung zur Datenbank aufgebaut. Als Parameter benötigt diese Funktion den Namen des Rechners ($db_server = localhost), auf dem die Datenbank läuft, den Benutzernamen ($db_user = test), unter dem man sich mit der Datenbank verbinden möchte sowie das – hier leere – Passwort des Benutzers. Die Funktion liefert eine Verbindungs-ID, welche in der Variable $db_connection gespeichert wird, da sie zum späteren Schließen der Verbindung benötigt wird. Geht bei dem Verbindungsaufbau etwas schief (wenn z.B. das Passwort nicht korrekt ist), gibt der die-Teil eine entsprechende Fehlermeldung aus und beendet die Ausführung des Scripts.

Im nächsten Schritt wird durch die MySQL-Funktion mysql_select_db die Datenbank auf dem Datenbankserver ausgewählt (hier die Datenbank test), auf die sich alle folgenden SQL-Befehle, die mit der MySQL-Funktion mysql_query, beziehen. Auch hier wird eine Fehlermeldung ausgegeben (Datenbank existiert nicht oder Benutzer hat nicht die nötigen Rechte), wenn dies nicht möglich ist.

Jetzt kann mit der MySQL-Funktion mysql_query ein SQL-Statement abgesetzt werden, welches in diesem Fall die in der Datenbank enthaltenen Datensätze in ein Result-Set ($result) liest. Im folgenden wird mit der MySQL-Funktion mysql_num_rows abgefragt, wieviele Datensätze durch den Select-Befehl gefunden wurden und im Result-Set (Parameter $result) gelandet sind – das Ergebnis wird entsprechend ausgegeben. Danach kann mit dem MySQL-Befehl mysql_fetch_array jede einzelne gelieferte Zeile aus dem Result-Set ausgelesen werden. Der erste Parameter gibt das zu verarbeitende Result-Set an, während der zweite Parameter dieser Funktion fest legt, dass ein Assoziatives-Array in der Variable $line gespeichert werden soll. Alle gefundenen Datensätze werden damit Reihe für Reihe in der Tabelle, deren HTML-Code erzeugt wird, ausgegeben und zuätzlich Links zum Löschen und Bearbeiten des jeweiligen Datensatzes erzeugt. Diese Links enthalten in ihrer URL einen Parameter, der die zu tätigende Operation (edit bzw. delete) und die ID des zu behandelnden Datensatzes enthält.

Am Ende der Funktion wird mit dem MySQL-Befehl mysql_free_result das entsprechende Result-Set gelöscht. Dies ist insbesondere dann nötig, wenn ein Result-Set sehr viel Speicher benötigt und bei der Verarbeitung des Scripts noch einige Schritte durchgeführt werden müssen. Auf diese Weise wird unnötig belegter Speicher frei gegeben wodurch verhindert wird, dass allzu großzügiger Speicherverbrauch die Stabilität des Webservers in Gefahr bringt. Der vom Script benötigte Speicher wird nach Beendigung des Scripts zwar automatisch frei gegeben aber sicher ist sicher. Zum Schluß wird die Verbindung zur Datenbank, deren Verbindungs-ID in der Variable $db_connection gespeichert ist, mit Hilfe des MySQL-Befehls mysql_close geschlossen.

# gibt die Linkliste in einer Tabelle aus und erzeugt Links zum Aendern und Loeschen
# der einzelen Datensaetze
function list_links ()
{
    global $db_server, $db_name, $db_user, $db_password;

    $db_connection = mysql_connect ($db_server, $db_user, $db_password)
     or die ("Fehler beim Aufbau der Datenbankverbindung: " . mysql_errno ()
            . " - " . mysql_error () . "<br>");
    if (mysql_select_db ($db_name))
    {
        if ($result = mysql_query ("SELECT link_id, link_url, link_title, link_description"
                        . " FROM links"))
        {
            echo "\t\t" . mysql_num_rows ($result) . " Link(s)<br>\n";
            echo "\t\t<table border=\"1\" rules=\"all\">\n\t\t<tr>\n";
            echo "\t\t\t<th>URL</th>\n\t\t\t<th>Titel</th>\n";
            echo "\t\t\t<th>Beschreibung</th>\n\t\t</tr>\n";
            while ($line = mysql_fetch_array ($result, MYSQL_ASSOC))
            {
                echo "\t\t<tr>\n\t\t\t<td style=\"vertical-align:top\">"
                 . "<a href=\"" . $line["link_url"] . "\">"
                 . $line["link_url"]
                 . "</a></td>\n\t\t\t<td style=\"vertical-align:top\">"
                 . $line["link_title"] . "</td>\n\t\t\t<td>"
                 . $line["link_description"] . "</td>\n"
                 . "\t\t\t<td style=\"vertical-align:top\">"
                 . "&nbsp;<a href=\"?edit&id=" . $line["link_id"]
                 . "\">&auml;ndern</a>&nbsp;<a href=\"?delete&id="
                 . $line["link_id"] . "\">l&ouml;schen</a></td>\n"
                 . "\t\t</tr>\n";
            }
            echo "\t\t</table><br>\n";
        }
        else
            echo "Fehler beim Lesen der Datens&auml;tze: "
             . mysql_errno () . " - " . mysql_error () . "<br>\n";
    }
    else
        echo "Datenbank konnte nicht ausgew&auml;hlt werden: "
            . mysql_errno () . " - " . mysql_error () . "<br>";
    mysql_free_result ($result);
    mysql_close ($db_connection);
}

Die Funktion im nächsten Code-Abschnitt sorgt dafür, dass Link-Daten, die zuvor in einem Formular verändert und dem Skript per Post-Parameter übergeben wurden, in der Datenbank aktualisiert werden können. Sie liefert TRUE in dem Fall, dass die Aktualisierung erfolgreich durchgeführt werden konnte. Dabei werden die bisher bereits beschriebenen MySQL-Funktionen eingesetzt, die nun wohl keiner weiteren Erklärung bedürfen. Der einzige Unterschied liegt in der Benutzung der MySQL-Funktion mysql_db_query – und natürlich einem anderen SQL-Befehl, der die Linkdaten aktualisiert und nicht mehr ausliest. Mit dem MySQL-Befehl mysql_db_query kann man – im Unterschied zu mysql_query, bei dem ein SQL-Befehl an eine schon durch mysql_select_db ausgewählte Datenbank gerichtet wird – SQL-Befehle an eine Datenbank richten, die im ersten Parameter dieser Funktion angegeben ist. Dies erspart das explizite Auswählen der Datenbank, wenn man beispielsweise Daten aus mehreren Datenbanken gleichzeitig verarbeiten will. Beachten Sie bitte auch unsere Beispiele zur PHP isset Function sowie unsere Ausführungen zur Verwendung von PHP Arrays.

# Aktualisiert die Daten eines Links in der Datenbank
function update_link ()
{
    global $db_server, $db_name, $db_user, $db_password;
    $retval = TRUE;

    $db_connection = mysql_connect ($db_server, $db_user, $db_password)
     or die ("Fehler beim Aufbau der Datenbankverbindung: " . mysql_errno ()
            . " - " . mysql_error () . "<br>");
    $sql_stmnt = "UPDATE links SET link_url = '" . $_POST['url']
         . "', link_title = '" . $_POST['title']
         . "', link_description = '"
         . nl2br ($_POST['description'])
         . "' WHERE link_id = " . $_POST['id'];
    if (!$result = mysql_db_query ($db_name, $sql_stmnt))
    {
        echo "Fehler beim Aktualisieren des Datensatzes: "
         . mysql_errno () . " - " . mysql_error () . "<br>\n";
        $retval = FALSE;
    }
    mysql_close ($db_connection);

    return $retval;
}

Auch in der folgenden Funktion dürften keine weiteren Erklärungen vonnöten sein, da hier ausschließlich die zuvor beschriebenen Funktionen zum Einsatz kommen. Es wird lediglich ein SQL-Befehl zum Löschen eines Datensatzes abgesetzt, dessen ID dem Script per Get-Parameter (in der URL) übergeben wurde.

# Loescht einen Eintrag aus der Datenbank
function drop_link ()
{
    global $db_server, $db_name, $db_user, $db_password;
    $retval = TRUE;

    $db_connection = mysql_connect ($db_server, $db_user, $db_password)
     or die ("Fehler beim Aufbau der Datenbankverbindung: " . mysql_errno ()
            . " - " . mysql_error () . "<br>");
    if (!$result = mysql_db_query ($db_name, "DELETE FROM links WHERE link_id = " . $_GET['id']))
    {
        echo "Fehler beim L&ouml;schen des Datensatzes: "
         . mysql_errno () . " - " . mysql_error () . "<br>\n";
        $retval = false;
    }
    mysql_close ($db_connection);

    return $retval;
}

Die Aufgabe der folgenden Funktion ist es einen neuen Datensatz, welcher in einem Formular eingegeben wurde, mit Hilfe des entprechenden SQL-Befehls in der Datenbank abzulegen. Alle dazu nötigen Link-Daten werden von einem Formular, das weiter unten erzeugt wird, per Post-Parameter übergeben.

# fuegt einen neuen Link in die Datenbank ein
function insert_link ()
{
    global $db_server, $db_name, $db_user, $db_password;
    $retval = TRUE;

    # Datensatz speichern
    $db_connection = mysql_connect ($db_server, $db_user, $db_password)
     or die ("Fehler beim Aufbau der Datenbankverbindung: " . mysql_errno ()
            . " - " . mysql_error () . "<br>");
    $sql_stmnt = "INSERT INTO links (link_url, link_title, link_description)"
         . " VALUES ('" . $_POST['url'] . "', '" . $_POST['title']
         . "', '" . nl2br ($_POST['description']) . "')";
    if (!$result = mysql_db_query ($db_name, $sql_stmnt))
    {
        echo "Fehler beim Einf&uuml;gen des Links: "
         . mysql_errno () . " - " . mysql_error () . "<br>\n";
        $retval = false;
    }
    mysql_close ($db_connection);

    return $retval;
}

Im nächsten Code-Abschnitt werden die Link-Daten eines Datensatzes, dessen Link-ID der Funktion als Parameter übergeben wird, ausgelesen und in einem Assoziativen-Array gespeichert. Diese Link-Daten werden von der Funktion als Rückgabewert geliefert. Auch hierzu dürfte keine weitere Erklärung mehr erforderlich sein.

# liest die Linkdaten des Datensatzes mit der uebergebenen ID
# und liefert ein Assoziatives Array mit den gelesenen Daten
function read_link ($id)
{
    global $db_server, $db_name, $db_user, $db_password;

    $db_connection = mysql_connect ($db_server, $db_user, $db_password)
     or die ("Fehler beim Aufbau der Datenbankverbindung: " . mysql_errno ()
            . " - " . mysql_error () . "<br>");
    $sql_stmnt = "SELECT link_url, link_title, link_description FROM links "
            + "WHERE link_id = " . $id;
    if ($result = mysql_db_query ($db_name, $sql_stmnt))
        if ($line = mysql_fetch_array ($result, MYSQL_ASSOC))
            $link = array (    'url' => $line['link_url'],
                    'title' => $line['link_title'],
                    'description' => ereg_replace ("<br />", "", $line['link_description']));
    else
        echo "Fehler beim Lesen des Datensatzes: "
         . mysql_errno () . " - " . mysql_error () . "<br>\n";
    mysql_close ($db_connection);

    return $link;
}

Der Rest des Skripts dient lediglich der Steuerung der HTML-Ausgabe und der Aufruf-Logik (Reaktion auf die dem Skript übergebenen Parameter). Im nächsten Abschnitt wird für den Fall, dass im Query-String (Get-Parameter in der URL) der Parameter new übergeben wurde das Einfügen eines neuen Datensatzes eingeleitet. Wurden bereits Linkdaten übergeben, so wird nach einer positiven Plausibilitätskontrolle die Speicherung des Datensatzes eingeleitet. Bei Eingabefehlern werden die Daten für den nächsten „Versuch” vorbelegt und später mit dem Formular eingeblendet.

# Neuen Eintrag speichern
if (in_array ("new", split ("&", $_SERVER['QUERY_STRING'])))
{
    echo "\t\tNeuen Link einf&uuml;gen...<br>\n";
    # vor dem Speichern auf Gueltigkeit der URL pruefen, sowie auf den Link-Titel
    if (Eingabe_plausi () && insert_link ())
        echo "\t\tDatensatz eingef&uuml;gt!<br>\n";
    else
    {
        # bei Eingabefehler Datenfelder wieder vorbelegen
        $url = isset ($_POST['url']) ? $_POST['url'] : "";
        $title = isset ($_POST['title']) ? $_POST['title'] : "";
        $description = isset ($_POST['description']) ? $_POST['description'] : "";
    }
}

Wird dem Skript der Parameter edit übergeben, so werden die Link-Daten des Links mit der ebenfalls übergebenen Link-ID eingelesen und im später erzeugten Formular vorbelegt. Stammen die Parameter aus einem schon zuvor ausgegebenen Formular, so werden die Daten nach positiver Plausibilitätskontrolle in die Datenbank übernommen. Eine negative Plausibilitätskontrolle führt zu einer erneuten Editiermöglichkeit in einem Formular, wobei die Daten erneut vorbelegt werden.

# Eintrag editieren
if (in_array ("edit", split ("&", $_SERVER['QUERY_STRING'])))
{
    echo "\t\tLink &auml;ndern...<br>\n";
    # vor dem Speichern auf Gueltigkeit der URL pruefen, sowie auf den Link-Titel
    if (Eingabe_plausi () && $updated = update_link ())
        echo "\t\tLink aktualisiert!<br>\n\t\t<br><a href=\"?list\">Links anzeigen</a>\n";
    else
        if (!isset ($_POST['id']))
        {
            # Daten zur Vorbelegung der Eingabefelder aus der Datenbank lesen
            if ($link_data = read_link ($_GET['id']))
            {
                $url = $link_data['url'];
                $title = $link_data['title'];
                $description = ereg_replace ("<br />", "", $link_data['description']);
            }
        }
        else
        {
            # bei Eingabefehler Datenfelder wieder vorbelegen
            $url = $_POST['url'];
            $title = $_POST['title'];
            $description = $_POST['description'];
        }
}

Beim Editieren sowie bei der Neuanlage eines Datensatzes (Query-String enthält new oder edit) wird durch den nächsten Code-Abschnitt ein HTML-Formular erzeugt und evtl. mit zuvor aus der Datenbank eingelesenen oder eingegebenen (im Falle zuvor fehlgeschlagener Plausibilitäten) Daten vorbelegt.

# Formular zum Editieren und bei Neuanlage anzeigen und evtl. mit Daten vorbelegen
if ((in_array ("edit", split ("&", $_SERVER['QUERY_STRING'])) && !isset ($updated))
¦¦ in_array ("new", split ("&", $_SERVER['QUERY_STRING'])))
{
    printf ("\t\t<form action=\"%s\" method=\"post\">\n",
        in_array ("new", split ("&", $_SERVER['QUERY_STRING'])) ? "?new" : "?edit");
    if (in_array ("edit", split ("&", $_SERVER['QUERY_STRING'])))
        printf ("\t\t\t<input type=\"hidden\" name=\"id\" type=\"text\" value=\"%d\"><br>\n",
            isset ($_GET['id']) ? $_GET['id'] : $_POST['id']);
    printf ("\t\t\tURL: <input name=\"url\" type=\"text\" size=\"100\" maxlength=\"100\" "
        + "value=\"%s\"><br>\n", isset ($url) ? $url : "");
    printf ("\t\t\tTitel: <input name=\"title\" type=\"text\" size=\"100\" maxlength=\"100\" "
        + "value=\"%s\"><br>\n", isset ($title) ? $title : "");
    printf ("\t\t\t<span style=\"vertical-align:top;\">Beschreibung:</span>"
        + "<textarea name=\"description\" cols=\"50\" rows=\"10\">%s</textarea><br>\n",
        isset ($description) ? $description : "");
    printf ("\t\t\t<input type=\"submit\" value=\"%s\">\n\t\t\t<input type=\"reset\" "
        + "value=\" Abbrechen \">\n",
        in_array ("new", split ("&", $_SERVER['QUERY_STRING'])) ?
        " Einf&uuml;gen " : " &Auml;ndern ");
    printf ("\t\t</form>\n\t\t<br><a href=\"?list\">Links anzeigen</a>\n");
}

Wird dem Skript über das Query-String der Parameter delete übergeben, so wird der Datensatz mit der ebenfalls per Get-Parameter übergebenen ID gelöscht.

# Datensatz aus Datenbank loeschen
if (in_array ("delete", split ("&", $_SERVER['QUERY_STRING'])))
{
    echo "\t\tLink l&ouml;schen...<br>\n";
    if (drop_link ())
        echo "\t\tDatensatz gel&ouml;scht!<br>\n";
    echo "\t\t<br><a href=\"?list\">Links anzeigen</a>\n";
}

Der letzte Abschnitt listet mit Hilfe der Funktion list_links die in der Datenbank vorhandenen Datensätze auf, wenn im Query-String der Parameter list zu finden ist. Beschreibungen zu Funktionen und Sprachelementen von PHP finden Sie um Bereich PHP Beispiele.

# Datenbestand ausgeben
if (in_array ("list", split ("&", $_SERVER['QUERY_STRING'])) ¦¦ $_SERVER['QUERY_STRING'] == "")
{
    echo "\t\tLinks anzeigen...<br>\n";
    list_links ();
    echo "\t\t<a href=\"?new\">Link anlegen</a>\n";
}
?>