Wie man eine Access-Datenbank ins Internet bringt (6)

Nun, wir haben das PHP-Skript admin.php durchgearbeitet. Verkürzt kann man sagen, es war für die Präsentation der vier Administrations-Möglichkeiten zuständig. Löschen, modifizieren/aktualisieren, angucken oder erzeugen von Büchern in der Buch-Datenbank. Nun muss es natürlich auch einen Teil bzw. ein Skript geben, das diese Aktionen auszuführen in der Lage ist. Und das gibt es auch. Das nächste zu besprechende PHP-Skript heißt action.php. Wieder gebe ich es als erstes in ganzer Länge wieder:


<?php
// No Cache
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

// MySQL Zugangsdaten
$database="XXXXXXX";
$host="localhost";
$user="XXXXXXX";
$password="XXXXXXX";
$table="BUECHER_GEL";

// Verbindung zur Datenbank herstellen
mysql_connect($host,$user,$password);
mysql_select_db($database) or die( "Unable to select database");

// POST Variable in eine eigene Variable ueberfuehren.
$rawdata = $_POST;

// Keine Aktion, keine Kekse.
if (array_key_exists('action', $rawdata))
{

    // Erstmal HTML Header
    echo '
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <title>Buecher Datensatz</title>
    </head>
    <body>


<table>
    ';

    // Was soll gemacht werden
    $action = $rawdata['action'];

    // Mit welcher ID?
    $id     = $rawdata['id'];

    // Aktion muss Kleinbuchstaben sein
    $action = strtolower($action);

    // Wenn wir eine ID haben den Datensatz holen
    if ($id)
    {
        // Mit der ID den Datensatz abfragen
        $query      = "select * from $table where id = '". $id . "'";
        $result     = mysql_query($query);

        // Und sich den Datensatz merken, wird fuer VIEW und MODIFY benoetigt
        $datensatz  = mysql_fetch_assoc($result);

        // Ging alles gut?
        if (!$result)
        {
            $message  = 'Invalid query: ' . mysql_error() . "\n";
            $message .= 'Whole query:   ' . $query;
            die($message);
        }

    }

    // DELETE
    // Datensatz loeschen, das muessen wir nicht extra via HTML Form/POST
    // einem weiteren Script geben, das koennen wir hier direkt erledigen
    if ( $id and ($action == "delete") )
    {
        // Datensatz loeschen
        $query  = "delete from $table where id = '". $id . "'";
        $result = mysql_query($query);

        // Ging alles gut?
        if (!$result)
        {
            $message  = 'Invalid query: ' . mysql_error() . "\n";
            $message .= 'Whole query:   ' . $query;
            die($message);
        }

        echo "

Loeschung erfolgreich";
        echo "
";
        echo '<a href="admin.php">Zurueck zur Admin-Seite</a>';
    }

    // VIEW
    // Datensatz anzeigen
    if ( $id and ( $action == "view" ) )
    {
        // Den bereits abgefragten Datensatz "ablaufen"
        foreach ($datensatz as $feld => $element)
        {
            // Alle Felder ausser dem Feld 'id' anzeigen
            // Man koennte auch die ID mitausgeben, aber viel Nutzen hat
            // diese Information nicht...
            if ($element and ($feld != "id") )
            {
                echo "

<tr>";
                echo "

<td>$feld</td>


";
                echo "

<td>$element</td>


";
                echo "</tr>


";
            }
        }
    }

    // CREATE
    // MODIFY
    //
    // CREATE und MODIFY sind an sich sehr aehnlich
    // Fuer beides braucht man eine Eingabemaske fuer Datensaetze
    // Bei MODIFY waeren die Felder vorbelegt (man will ja etwas aendern).
    // Bei CREATE sind die Felder natuerlich alle leer
    //
    // Unterscheiden laesst sich das relativ einfach
    // Wurde eine ID mit uebergeben (also ausgewaehlt)
    // ist es ein MODIFY, ansonsten ein CREATE

    if ( ($action == "create") or ($action == "modify") )
    {

        // Da beide Vorgaenge nur dadurch definiert werden ob
        // es eine ID ausgewaehlt wurde, entsprechenden Hinweis geben
        if ( ($action == "create") and $id )
        echo "Create mit einer ID ist ein Modify 🙂 
";

        // Nur hier macht ein submit Sinn
        echo "

<form action = \"change.php\" method = \"post\">";

        // Datenbank nach Tabellenkoepfen fragen
        $query="show columns from $table";
        $result=mysql_query($query);

        // Kann eigentlich nicht schiefgegangen sein...
        if (!$result)
        {
            $message  = 'Invalid query: ' . mysql_error() . "\n";
            $message .= 'Whole query:   ' . $query;
            die($message);
        }

        // Noch ein bisschen HTML
        echo "

";
        echo "Bitte in die entsprechenden Felder eintragen";

        // Aus der Tabellendefinition die Eingabefelder aufbauen
        while ( $row = mysql_fetch_assoc($result) )
        {
            $feldname = $row['Field'];
            $typ      = $row['Type'];

            $inhalt = $datensatz{$feldname};
            $sauber = trim($inhalt);
            $inhalt = $sauber;
    
            // Groesse 
            $fieldsize  = ereg_replace("[^0-9]", "", $typ);
   
            // Das Feld 'id' soll ausgeblendet werden, muss
            // aber trotzdem uebergeben werden, daher wird 'id'
            // entsprechend "versteckt" uebergeben.
 
            if ( $feldname == "id" ) 
            {
                echo "<input type=\"hidden\" name=\"$feldname\" value=\"$inhalt\">"; 
                continue; 
            }            

            // Der Feldname der Tabelle
            echo "

<tr>";
            echo "

<td>$feldname</td>


";

            // varchar(1)
            if ( $fieldsize == 1 )
            {
                if    ($inhalt) { echo "

<td><input type=checkbox value=\"1\" name = \"$feldname\" checked></td>


"; }
                else            { echo "

<td><input type=checkbox value=\"1\" name = \"$feldname\"></td>


"; }
                echo "</tr>


";
            }    

            // Von vchar(2) bis vchar(199) = textinput = Eingabezeile
            if ( ($fieldsize > 1) AND ($fieldsize < 200) )
            {
                if    ($inhalt) { echo "

<td><input size=\"80\" name=\"$feldname\" value=\"$inhalt\"></td>


"; }
                else            { echo "

<td><input size=\"80\" name=\"$feldname\"></td>


"; }
                echo "</tr>


";
            }    

            // Ab vchar(200) macht eine textarea Sinn 
            if ( $fieldsize >= 200 )
            {
                if    ($inhalt) { echo "

<td><textarea cols=\"80\" rows=\"5\" name=\"$feldname\">$inhalt</textarea></td>


"; }
                else            { echo "

<td><textarea cols=\"80\" rows=\"5\" name=\"$feldname\"></textarea></td>


"; }
                echo "</tr>


";
            }    

        }
    // Und hier wieder ein Submit
    echo '


        <input type="submit"/> <input type="reset"/>
        

        </form>


    ';

    }
}

// HTML sauber wieder schliessen
echo '
</table>


</body>
</html>
';
// Verbindung schliessen
mysql_close();
?>


Und wieder kannst du hier im Blog den Quer-Scrollbalken nutzen, um bis ans Ende der Zeilen schauen zu können.

Jetzt krieg erst mal keinen Schock. Ich weiß, das ist ein langes, ein heftiges Skript. Aber wir gehen wieder, wie schon gewohnt, in kleinen und kleinsten Schritten vor. Ich werde dir jedes einzelne Code-Element erklärend darlegen. 🙂

Los geht’s! Die ersten beiden Zeilen unter „No Cache“ bewirken, wie in admin.php auch, dass der Browser die Seite nicht zwischenspeichert, da das Ablaufdatum in der Vergangenheit liegt.

Wieder muss das Skript die Zugangsdaten zur MySQL-Datenbank liefern. Sonst könnte kein Zugriff auf die Datenbank erfolgen. Fünf Elemente sind es, wie gewohnt. Das fünfte weist den Namen der betroffenen Datenbank-Tabelle der Variablen $table zu. Und wieder wird auch die Verbindung aufgebaut (mysql_connect und mysql_select_db).

Genau wie in admin.php wird jetzt der gesamte Inhalt von $_POST in die Variable $rawdata überführt. Und was ist das genau, was da überführt wird? Richtig! Das, was ein Besucher deiner Site ins Formular eingegeben hat. Welches Formular? Dasjenige, das die admin.php zuvor generiert hat. Es konnte ein Buch, verbunden mit einer Aktion, z.B. „angucken“ gewählt werden.

Vielleicht schauen wir uns mal an, was wir normalerweise nicht zu sehen kriegen im Programmflow: den Inhalt von $rawdata. Einmal angenommen, du als Datenbank-Administrator und Backend-Nutzer hättest das Buch Winnetou III und damit verbunden die Aktion „angucken“ gewählt (VIEW). In dem Fall enthielte $rawdata:

array(2) { [„id“]=> string(2) „86“ [„action“]=> string(4) „view“ }

Was bedeutet das? Es heißt: In $rawdata ist ein Array, also ein Datenfeld mit zwei Elementen. Im ersten Element ist dem Schlüssel id der Wert 86 zugeordnet, im zweiten Element ist dem Schlüssel action der Wert view zugeordnet. Beide Schlüssel sind vom Typ String, also Zeichenkette. Die erste Zeichenkette hat zwei Stellen, die zweite vier. Woher stammen die Daten? Antwort: Du als Backend-Nutzer hast dich für das Buch Winnetou III entschieden (id 86) und für die Aktion view, das Buch Winnetou III soll also angeschaut werden. Jetzt wissen wir, was in $rawdata enthalten ist.

Zur Zwischenorientierung: Wir bewegen uns derzeit im PHP-Skript action.php.

Was folgt, ist eine sehr umfassende IF-Struktur. Betrachte das Skript bei ca. Zeile 21:

if (array_key_exists(‚action‘, $rawdata))

Danach folgt eine öffnende geschweifte Klammer, welche die IF-Struktur beginnen lässt. Sie schließt sich erst wieder bei ca. Zeile 254, ist also wirklich umfassend. Und welche Bedingung wird hier formuliert und für welchen Programmablauf? Antwort: Wenn der Schlüssel action im Array $rawdata vorhanden ist, ja dann, und nur dann wird der Programmablauf zwischen den äußersten geschweiften Klammern ausgeführt. Konkret heißt das, der Backend-Nutzer muss sich für eine der vier Aktionen DELETE, MODIFY, VIEW oder CREATE entschieden haben, sonst geschieht nichts.

Na gut, wenden wir uns dem zu, was zwischen diesen äußersten geschweiften Klammern steht. Hier wird erst mal wieder ein HTML-Kopf gebaut. „echo“ erzeugt eine Ausgabe, das einfache Anführungszeichen lässt beginnen, was ausgegeben werden soll. Ignoriere hier ruhig den DOCTYPE-Teil, er ist für uns jetzt nicht so wichtig. <html> öffnet ein HTML-Dokument. <head> öffnet dessen Kopfbereich. Zwischen <title> und </title> steht, was im Browser-Tab zu sehen sein soll: „Buecher Datensatz“. </head> schließt den HTML-Kopf. <body> öffnet den Körperbereich. <table> lässt eine Tabelle beginnen. Das einfache Anführungszeichen und das Semikolon beenden den echo-Befehl. So far, so good. 🙂

$action = $rawdata[‚action‘];
$id     = $rawdata[‚id‘];

Jetzt holt das Skript (klar, wir sind immer noch bei action.php) aus dem Array $rawdata den Wert des Schlüssels action heraus und speichert ihn in der Variable $action. Sie beinhaltet jetzt eine der vier möglichen Aktionen DELETE, MODIFY, VIEW oder CREATE. Welche? Na die, die der Backend-Nutzer gewählt hat. Dann holt das Skript den Wert den Schlüssels id aus dem Array $rawdata. Welche ID? Na die, die zu dem Buch gehört, das der Backend-Nutzer gewählt hat.

Mit

$action = strtolower($action);

wird sichergestellt, dass der Action-Wert in Kleinbuchstaben vorliegt. Nun folgt eine IF-Struktur innerhalb der sehr umfassenden IF-Struktur:

if ($id)

Nur, wenn es id auch gibt, geht es überhaupt weiter. Mit dieser nun in $id gespeicherten ID wird nun eine SQL-Abfrage generiert:

select * from $table where id = ‚“. $id . „‚

Das heißt: Wähle alle Felder aus der Tabelle BUECHER_GEL, dort, wo die ID 86 lautet. Also

Autor Nachname
Autor Vorname
Titel
Untertitel
Ort
Verlag
Jahr
Kategorie
Art
Übersetzung von – in
wann gelesen etwa
Kommentar

bei ID 86.

$result = mysql_query($query);

Führe diese Abfrage aus und speichere das zurückerhaltene Objekt in der Variable $result. Wie viele Datensätze bzw. Bücher ergibt die Abfrage? Richtig, eins. Nur Buch 86. Diesen Datensatz merkt sich das Skript jetzt noch mittels

$datensatz  = mysql_fetch_assoc($result);

… also der üblichen Objekt-auslesen-Struktur. Es folgt jetzt noch kurz die obligate Prüfsequenz, sollte bei der Abfrage etwas schiefgelaufen sein. Zur Orientierung: Wir haben jetzt ca. Zeile 67 von action.php passiert.

Und es geht weiter. 🙂 Es folgt der Codeblock zum Löschen eines Buches. Dazu braucht es kein HTML-Formular. Weißt du auch warum? Genau, es werden ja dabei keine Felder modifiziert, sondern das ganze Buch mit allen seinen zwölf Feldern wird gelöscht.

if ( $id and ($action == „delete“) )

sagt: Wenn eine ID gesetzt ist und die Variable $action den Wert delete hat, nur dann führe das Folgende aus. Und dieses Folgende beginnt mit wieder mit der Zuweisung einer SQL-Abfrage:

delete from $table where id = ‚“. $id . „‚

Das heißt: Lösche alle Felder, lösche den ganzen Datensatz, lösche das ganze Buch aus der Tabelle BUECHER_GEL dort, wo die ID 86 lautet. Der edle Indianer soll nicht mehr sein, Winnetou III muss in die ewigen Jagdgründe gelangen.

$result = mysql_query($query);

führt das auch wirklich aus und speichert wie immer das Ergebnis in $result. Nachdem der Indianer seiner Datenbank-Existenz beraubt wurde, informiert uns

echo „<p>Loeschung erfolgreich“;
echo „<br />“;
echo ‚<a href=“admin.php“>Zurueck zur Admin-Seite</a>‘;

darüber und gibt einen Link aus, mit dem wir zur Admin-Seite/zum Admin-Skript admin.php zurück können. Glückwunsch! 🙂 Du hast den DELETE-Block verstanden.

Machen wir doch gleich weiter mit dem VIEW-Block.

if ( $id and ( $action == „view“ ) )

Dieser IF-Struktur-Beginn fragt wie schon üblich nach der vom Backend-Nutzer gewählten Aktion. Der nachfolgende Programmcode wird nur ausgeführt, wenn sie view lautet.

foreach ($datensatz as $feld => $element)

Die sogenannte FOR-EACH-Schleife ist prädestiniert zum Ablaufen von Datenfeldern. Sie lautet versprachlicht: Aus dem Datensatz $datensatz weise bei jedem Schleifendurchlauf der Variablen $feld den Feldnamen (Array-Schlüssel) zu und weise bei jedem Schleifendurchlauf der Variablen $element den Schlüssel-Wert zu. Das klingt dir zu schwer? Dann programmiere es einfach trotzdem. Man kann nicht verlangen, dass alles aktives Wissen wird. Merke dir nur, dass die FOR-EACH-Schleife die zwölf Felder des gewählten Buches abklappert.

if ($element and ($feld != „id“) )

heißt: Der Parser/Interpreter/Apache-Server soll alle Felder nehmen, außer ID. Das dreizehnte, normalerweise unsichtbare Feld ID wird hier nicht gebraucht. Der Block

echo „<tr>“;
echo „<td>$feld</td>“;
echo „<td>$element</td>“;
echo „</tr>“;

sorgt für die tabellarische Ausgabe des Buches. Schaltflächen zum Absenden oder Zurücksetzen werden bei view nicht gebraucht, und, wie du in Bild 6-1 siehst, auch nicht angezeigt.

keine_Schaltflaechen_notwendig-02

Bild 6-1

Du hast den VIEW-Block geschafft.

Die Blöcke CREATE und MODIFY sind an sich sehr ähnlich. Beide machen eine Eingabemaske für die Datensätze erforderlich. Bei MODIFY wären die Felder vorbelegt (denn man will ja etwas ändern), bei CREATE sind die Felder natürlich alle leer. Unterscheiden lässt sich das relativ einfach: Wurde eine ID mit übergeben (also ausgewählt), ist es ein MODIFY, ansonsten ein CREATE.

if ( ($action == „create“) or ($action == „modify“) )

Das liegt bei ca. Zeile 123. Die IF-Struktur behandelt erst mal beide Fälle. Im Falle CREATE

if ( ($action == „create“) and $id )

wird das externe PHP-Skript change.php (wechsle!) aufgerufen. Das geschieht mit:

<form action = \“change.php\“ method = \“post\“>

Wir werden dieses Skript in „Wie man eine Access-Datenbank ins Internet bringt (7)“ noch genauestens besprechen.

Jetzt aber erst mal eine erneute SQL-Abfrage:

show columns from $table

heißt: Zeige alle Spalten der Tabelle BUECHER_GEL. Das Ergebnis landet wie immer in $result. Und wieder die Prüfsequenz, also alles wie gehabt und bekannt. Vor der Schleife noch ein kurzer HTML-Teil:

echo „<p>“;
echo „Bitte in die entsprechenden Felder eintragen“;

Es folgt eine große Schleife. Sie reicht von ca. Zeile 151 bis ca. Zeile 201. Die Schleife selber lautet:

while ( $row = mysql_fetch_assoc($result) )

… also: Solange du, Parser/Interpreter/Apache-Server Datensätze bei der Spaltenausgabe finden kannst, führe den Code innerhalb der geschweiften Klammern aus. Hör damit auf, wenn du beim letzten Datensatz angelangt warst. Wir erhalten also die Tabellen-Spaltennamen aller Bücher.

$feldname = $row[‚Field‘];
$typ      = $row[‚Type‘];

Erinnert sehr an unser gutes altes query.php, nicht wahr? Der Variablen $feldname wird der Name des Feldes zugewiesen, z.B. „Verlag“. Der Variablen $typ wird der Typ des Feldes zugewiesen, z.B. „varchar(100)“, das wäre dann der Typ „variable Zeichenanzahl mit 100 Zeichen“. Der Variablen $inhalt wird der Inhalt des aktuellen Feldes zugewiesen, z.B. „Karl-May-Verlag“. Mit

$sauber = trim($inhalt);
$inhalt = $sauber;

werden Leerzeichen, die am Beginn oder am Ende von $inhalt sein könnten, entfernt. Mit

$fieldsize  = ereg_replace(„[^0-9]“, „“, $typ);

wird die Größe des Feldes ermittelt, also die Anzahl der Zeichen. Die Funktion ereg_replace entfernt hier alles, was keine Ziffer ist. Aus „varchar(100)“ wird so „100“.

Wenn die Schleife gerade bei der id vorbeikommt, der Namen des Feldes also „id“ lautet, wird das Formularelement

<input type=\“hidden\“ name=\“$feldname\“ value=\“$inhalt\“>

ausgegeben. Versteckt (hidden), weil die ID nicht zu sehen sein muss. Übergeben werden muss die ID dennoch, wie sonst sollte das letzte Skript change.php (Blog-Teil 7) seine SQL-Befehle an das richtige Buch adressieren? Und dann wird mittels „continue“ der Schleifendurchlauf an dieser Stelle unterbrochen (ID wird nicht in den echo-Ausgabe-Prozess übernommen) und die Schleife wird mit der nächsten Bedingung fortgesetzt. Danach folgt mit echo die Ausgabe des Feldnamens, z.B. „Verlag“ unter Heranziehung der eben gefüllten Variable $feldname. Die Tabellen-Tags erspare ich uns jetzt alle mal, die kennst du ja (Tabelle auf, Tabellenreihe auf, Tabellendaten auf, Tabellendaten zu, Tabellenreihe zu, Tabelle zu).

Es folgen nacheinander drei IF-Strukturen in der IF-Struktur in der umfassenden IF-Struktur, also dritte IF-Ebene. Diese drei sind für folgende Fälle:

  1. Feldgröße gleich 1
  2. Feldgröße größer 1 kleiner 200
  3. Feldgröße 200 oder größer

Abhängig davon wird

  1. ein Kontrollkästchen angelegt (checkbox)
  2. ein Eingabefeld angelegt (einfaches input)
  3. ein Textfeld angelegt (textarea)

Option 1 ist überflüssig, denn in der Tabelle BUECHER_GEL ist kein Feld nur ein Zeichen groß. Option 3 ist sinnvoll für Titel, Untertitel und Kommentar, weil diese recht lang werden können, kommt auf das Buch an. Also: abhängig von der Feldgröße wird das passende Eingabeformular-Element mit echo ausgegeben.

Wir haben es gleich! 🙂

Es folgen die Schaltflächen fürs „Absenden“ und „Zurücksetzen“ (letzteres, wenn der Backend-Nutzer sich mal vertippt hat und das auch gleich merkt). Zum Schluss wird wieder so einiges geschlossen:

  1. die Schleife
  2. der Abschnitt (Paragraph)
  3. das Formular
  4. der echo-Teil mit beendendem einfachen Anführungszeichen
  5. der PHP-Befehl mit einem Semikolon
  6. die größere IF-Struktur und die umfassende IF-Struktur
  7. die Tabelle
  8. der HTML-Körper
  9. das HTML-Dokument
  10. nochmal ein PHP-Befehl
  11. die SQL-Verbindung
  12. und dann noch das ganze Skript

Fast fertig! 🙂 Nur noch ein paar Erläuterungen: Das soeben besprochene Skript action.php leistet, dass die Feldnamen samt ihren Inhalten aufgelistet werden. Alles immer für genau ein Buch. view zeigt nur das Buch an, wie es ist. create und modify liefern Eingabefelder, denn sowohl, wenn der Backend-Nutzer ein neues Buch anlegen will, als auch wenn er ein Buch modifizieren will, braucht er natürlich Eingabefelder. Und die vierte Option delete für löschen hatten wir ja eben schon.

Das von action.php somit bereitgestellte Eingabe-Formular ruft dann zur Weiterverarbeitung das Skript change.php auf. Sofern vom Backend-Nutzer nicht view oder delete gewählt wurde. change.php besprechen wir im Blog-Teil 7 gleich im Anschluss.

Herzlich Glückwunsch! Du hast das Skript action.php geschnallt. Oder doch noch nicht so ganz? Dann bitte tüchtig googeln, in Foren fragen, dieses Blog kommentieren …

Navigiere nun bitte zum nächsten Eintrag von streethawk68: Wie man eine Access-Datenbank ins Internet bringt (7)

Advertisements

Über streethawk68

43 years old IT-Fan
Dieser Beitrag wurde unter Uncategorized abgelegt und mit , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s