3.3 Serverseitige Verarbeitung (Formularüberprüfung)

Wir nehmen für unser Beispiel an, dass es auf dem Server eine MySQL-Datenbank mit dem Namen cms gibt, zu der eine Tabelle namens templates gehört. In dieser Tabelle seien bislang folgende Daten gespeichert:

id name
1 einspaltig
2 zweispaltig
3 dreispaltig

Die id-Spalte speichert Autoincrement-Werte, wie sie in Datenbanktabellen häufig verwendet werden. In der Spalte name werden Template-Namen gespeichert. Diese Namen sollen tabellenweit eindeutig (unique) sein.

Unser serverseitiges PHP-Script check_DB_value.php, das in der Ajax-JavaScript-Funktion ajax_check_DB_value() aufgerufen wird, hat also die Aufgabe, zu prüfen, ob der übergebene Wert, den der Benutzer im Feld eingegeben hat, in der Datenbank-Tabellenspalte name bereits vorhanden ist oder nicht.

Das PHP-Script hat in unserem Beispiel folgenden Code:

<?php
function  end_with_error($text) {
    $begin = "<span class=\"errortext\">";
    $end = "</span>";
    echo $begin . $text . $end;
    exit();
}
 
function  end_with_success($text) {
    $begin = "<span class=\"successtext\">";
    $end = "</span>";
    echo $begin . $text . $end;
    exit();
}
 
$dbh = mysql_connect("localhost", "dbuser", "dbpassword");
if(!$dbh) 
    end_with_error("Keine DBMS-Verbindung!");
$sql = "USE cms";
$sql_result  = @mysql_query($sql, $dbh);
if(!$sql_result) 
    end_with_error("Keine Verbindung  zur Datenbank!");
if(! isset($_GET['table']) or empty($_GET['table']))
    end_with_error("Keine Datenbanktabelle  angegeben!");
if(! isset($_GET['field']) or empty($_GET['field']))
    end_with_error("Keinen Feldnamen  angegeben!");
if(! isset($_GET['type']) or empty($_GET['type']))
    end_with_error("Keinen Feldtyp angegeben!");
if($_GET['type'] != "string" and  $_GET['type'] != "num")
    end_with_error("Falschen Feldtyp  angegeben!");
if(! isset($_GET['value']) or  empty($_GET['value']))
    end_with_error("Keinen Wert angegeben!");
if(! isset($_GET['excldbid']))
    end_with_error("Keine Angabe zu auszuschließenden 
                         Datensätzen!");
if($_GET['type'] == "string")
    $field_value = 
       mysql_real_escape_string("'" . $_GET['value'] . "'");
else
    $field_value = 
       mysql_real_escape_string($_GET['value']);
$sql = "SELECT  COUNT(*) AS  count  FROM " .  $_GET['table'] . 
         " WHERE " . $_GET['field'] . " = " . $field_value;
if((int) $_GET['excldbid'] > 0)
    $sql .= " AND id <> " . (int) $_GET['excldbid'];
$sql_result  = @mysql_query($sql, $dbh);
if(!$sql_result) 
    end_with_error("Kein  Datenbankergebnis!");
else {
    $res = mysql_fetch_array($sql_result, MYSQL_ASSOC);
    if($res['count'] > 0) 
        end_with_error("Wert bereits  vorhanden! Bitte einen 
                             anderen Wert  eingeben!");
    else
        end_with_success("Der eingegebene Wert ist verfügbar!");
}
?>

Das Script enthält der Übersichtlichkeit halber zunächst zwei Funktionen, die zum Ausgeben von Daten und zum Beenden gedacht sind: end_with_error($text) ist für Negativ-Ausgaben gedacht, und end_with_success($text) für Erfolgsmeldungen. Beide Funktionen geben mit echo einen Text aus, den sie als Parameter übergeben bekommen. Die Funktionen unterscheiden sich lediglich in der CSS-Klasse, der sie dem span-Element zuordnen, in das sie die auszugebende Meldung verpacken. Diese CSS-Klassen (errortext und successtext) könnten z.B. in einem Stylesheet so definiert sein, dass Fehlermeldungen rot erscheinen, Erfolgsmeldungen dagegen schwarz oder grün.

Was das PHP-Script mit echo ausgibt, sind übrigens genau die Nutzdaten, die von der HTTP-Serverantwort an das aufrufende JavaScript übertragen werden, also diejenigen Daten, die JavaScript dynamisch in die angezeigte Webseite einbaut.

Unterhalb der beiden Funktionen end_with_error() und end_with_success() beginnt der direkt ausgeführte Scriptcode. Das Script baut zunächst mit mysql_connect() eine Verbindung zum MySQL-System des Servers auf. Die dabei übergebenen Parameter sind natürlich in einer anderen Umgebung entsprechend anzupassen. Anschließend wird das SQL-Statement USE cms an MySQL gesendet, um die gewünschte Datenbank auszuwählen.

Daran anschließend überprüft das Script seine per GET-Parameter erhaltenen Daten. Fehlen übergebene Parameter oder enthalten sie keine oder ungültige Werte, wird mit end_with_error() eine entsprechende Fehlermeldung ausgegeben.

In der zweiten Hälfte baut das Script dann das SQL-Statement der eigentlichen Prüfabfrage zusammen. Mit SELECT count(*) … wird ein Statement erzeugt, bei dem MySQL als Ergebnis nur die Anzahl der Datensätze (Tabellenzeilen) zurückliefert, auf die die formulierte WHERE-Klausel zutrifft.

Falls der GET-Parameter excldbid einen Wert größer 0 hat, wird die WHERE-Klausel dahingehend erweitert, dass der Datensatz, bei dem die Spalte id den Wert von excldbid hat, nicht mit berücksichtigt wird. Warum das? Ganz einfach: angenommen, das HTML-Formular, welches den Ajax-Request auslöst, ist ein Formular, in dem Daten eines bestehenden Templates geändert werden. In diesem Fall ist der vorbelegte Feldwert in der Datenbank natürlich schon vorhanden. Ein Klick auf Prüfen würde aus eben diesem Grund das für den Benutzer verwirrende Ergebnis Wert bereits vorhanden! Bitte einen anderen Wert eingeben! erzeugen. Um dies zu verhindern, kann beim Ändern eines bestehenden Datensatzes dessen id-Wert im Parameter excldbid übergeben werden.

Das PHP-Script kann seine Arbeit beenden, wenn das MySQL-Ergebnis vorliegt. Wurden mehr als 0 Datensätze gefunden, ist der Wert nicht mehr verfügbar. Entsprechende Meldungen werden mit echo ausgegeben und vom Ajax-JavaScript in die Webseite eingefügt.

Sofern nicht anders angegeben, steht der Inhalt dieser Seite unter Lizenz Creative Commons Attribution-ShareAlike 3.0 License