|
|
|
Hat jetzt bloß keiner meinen Workshop zu PHP in der letzten AMIGA aktuell gelesen oder hat sich jeder darauf verlassen, dass schon irgendjemand auf den Aufruf antwortet? Fakt ist, dass keine einzige Reaktion erfolgte! Somit ist es natürlich für mich, wie auch die anderen Artikelschreiber, schwierig zu erfahren, worüber man schreiben soll, damit es euch interessiert.
Da jedoch mySQL recht populär ist und auch als Portierung für den Amiga vorliegt, wird es wohl den einen oder anderen doch interessieren.
Also gibt es diesmal als Fortsetzung zum Kalender eine Notizfunktion. Die komplette Datenverwaltung überlassen wir dabei der mySQL-Datenbank.
Diesmal vorweg ein paar einführende Worte über den Aufbau und die Funktionsweise. Als "notizbuch.html" ist eine Einstiegsseite definiert, die Frames benutzt. Dadurch muss nicht immer die komplette Seite neu aufgebaut werden, sondern es kann ein Teil ausgetauscht werden (bei uns die Notizen rechts). Der linke Frame enthält ein leicht erweitertes PHP-Skript des Kalenders, genannt "notizkalender.php". Jede einzelne Monatszahl ist jetzt ein Link in der Form:
<a href="notizeintrag.php?tag=$tag&monat=$monat&jahr=$jahr" target=''> [hier steht die Monatszahl] </A> |
Beim Anklicken der Zahl wird also der Link geladen beziehungsweise unser neues Skript "notizeintrag.php" aufgerufen. Übergeben werden in URL- Notation die einzelnen Parameter: Tag, Monat und Jahr. Mittels 'target' wird der Frame definiert, in dem das Ergebnis angezeigt werden soll (also die rechte Fensterhälfte).
Zusätzlich wurde der Kalender noch so abgeändert, dass der Vorgängermonat über dem Kalender und der Nachfolgemonat unter dem Kalender platziert wird, und nicht mehr links/rechts davon. Eine Erweiterungsmöglichkeit wäre zum Beispiel, mehrere Monate im Voraus auszugeben (einfach mittels for- Schleife).
Wenden wir uns jetzt der neuen Datei "notizeintrag.php" zu. Es handelt sich wieder um PHP-Code, wie die Endung bereits verrät. Neu ist vor allem die Benutzung der mySQL-Funktionen.
Auch hierfür möchte ich Interessierte wieder auf das Amiga Magazin 08/2001 beziehungsweise online http://www.meicky-soft.de/amiga-magazin/mysql.html verweisen. Dort habe ich ausführlich die Installation von mySQL am Amiga beschrieben. Auch Datenbankdesign und SQL sind dort Themen des zweiten Kursteiles.
Bevor die Notizdatenbank benutzt werden kann, muss sie erst einmal
definiert werden. Da in der Amiga-Portierung das "CREATE DATABASE" Kommando
nicht korrekt funktioniert, ist mittels "makedir
Als nächstes muss noch die eigentliche Tabelle (die umgangssprachlich auch gern als Datenbank bezeichnet wird) angelegt werden. Zum Beispiel
CREATE TABLE notizbuch (id INT NOT NULL AUTO_INCREMENT,
datum DATE,
uhrzeit TIME,
text CHAR(100),
PRIMARY KEY(id)
);
|
Mögliche Datentypen sind (unter anderem) INT für Zahlen, REAL für Fließkommazahlen, DATE für Datumswerte, TIME für Zeitwerte, CHAR für eine definierte Anzahl an Zeichen. VARCHAR kann dynamisch bis zu 4096 Zeichen aufnehmen.
Jeder Satz erhält bei uns eine eindeutige Nummer (id). Damit wird er für Änderungen oder zum Löschen gefunden. Die Nummer wird automatisch von mySQL vergeben (der letzte Tabelleneintrag wird um eins erhöht). Für schnelleren Zugriff erklären wir dieses Feld auch als Indexfeld. PRIMARY legt außerdem fest, dass jede 'id' nur einmal benutzt werden kann, also nicht zwei Sätze mit identischer 'id' vorhanden sein können.
Mittels mysql_connect() wird eine Verbindung zum Datenbankserver hergestellt. Alternativ gibt es das mysql_pconnect()-Kommando, das eine persistente Verbindung herstellt. Das heißt, wenn mehrmals auf die Datenbank zugegriffen werden soll, bleibt die Verbindung bestehen und wird nicht immer neu aufgebaut.
Beide Funktionen erwarten den Namen des Hosts, einen Benutzernamen und dessen Passwort. Da alle diese Werte im Klartext übergeben werden müssen, sollten sie nicht direkt im PHP-Skript abgelegt werden, sondern per include-Anweiung eingebunden werden. Die separate Datei mit diesen Werten muss außerdem außerhalb des normalen Webspaces liegen (in der Regel htdocs- Verzeichnis). Nur so ist sichergestellt, dass niemand von außen per HTTP oder FTP auf die Datei zugreifen und deren Inhalt lesen kann.
Wenn die Verbindung hergestellt werden konnte, liefert die Funktion einen positiven Wert. Dann muss nur noch die Datenbank ausgewählt werden, mit der gearbeitet werden soll. Im Fehlerfall wird lediglich ein entsprechender Hinweis ausgegeben und das PHP-Skript abgebrochen.
$connID = @mysql_pconnect($mysqlhost, $mysqluser, $mysqlpasswd);
if($connID)
{
mysql_select_db($mysqldatabase); /* Datenbank connectieren */
return( $connID );
}
else
{
echo "<BR><font color='red'>Keine Verbindung zur Datenbank möglich !</font><BR>\n";
echo "Fehlerursache: " . mysql_error() . "<BR>\n";
exit(); /* Skript abbrechen */
}
|
Mittels SELECT wird in mySQL nach Datensätzen gesucht. Dabei können auch sehr komplexe Suchbedingungen und Gruppierungsanweisungen verwendet werden. Zusätzlich können auch noch Verknüpfungen mit anderen Tabellen ins Spiel kommen (JOIN). Wir beschränken uns jedoch auf eine ganz einfache Syntax: Alle Einträge zu einem Datum sollen angezeigt werden. Die zugehörigen Daten liefert der Aufruf von
SELECT * FROM notizbuch WHERE datum = '$suchdatum' ORDER BY uhrzeit; |
wobei die gefundenen Treffer nach der Uhrzeit sortiert ausgegeben werden sollen. Im PHP-Code muss das ganze noch in eine mysql_query() gepackt werden.
Weitere benötigte Funktionen sind
Jetzt muss nur noch eine Tabelle im HTML-Code ausgespuckt werden, damit eine saubere Formatierung im Browser möglich ist. Dabei werden die gefundenen Daten als Formular aufbereitet, so dass jederzeit einfach Änderungen an den Einträgen möglich sind.
Zuerst kommt jetzt der PHP-Code für die ganze Datenbankabfrage:
/* ab hier Anzeige des Tabelleninhalts (der Notizen) */
if(isset($jahr))
{
$suchdatum = date("Y-m-d",mktime(0,0,0,$monat,$tag,$jahr));
/* formatieren als jahr-monat-tag */
echo "Eintragungen für\n<H1>$tag. $monatstr[$monat] $jahr</H1><BR><BR>\n";
echo "<table border=0>\n";
echo " <tr><th>Uhrzeit</th><th>Eintragung</th><th>Aktionen</th></tr>\n";
/* Datenbankabfrage starten */
$result = mysql_query("SELECT * FROM notizbuch WHERE datum = '$suchdatum' ORDER BY uhrzeit");
if($result)
{
/* Anzahl Zeilen ermitteln */
$rows = mysql_num_rows($result);
if($rows > 0)
{
/* Tabellen-Inhalt ausgeben */
while($dbentry = mysql_fetch_object($result))
{
eintrag_zeigen($dbentry->id,
$dbentry->datum,
substr($dbentry->uhrzeit,0,5), /* Sekunden weg */
$dbentry->text);
}
}
else
{
echo "<tr><td colspan=3><i>keine Eintragungen vorhanden</i></td></tr>\n"; }
}
//else: Datenbank existiert nicht oder SQL-Fehler
/* entfernt die Ergebnisdaten aus dem Speicher */
mysql_free_result($result);
|
Fehlt uns noch die Funktion eintrag_zeigen(), die einen einzelnen gefundenen Datensatz als Formular aufbereitet erzeugt:
function eintrag_zeigen($dbid,$dbdatum,$dbuhrzeit,$dbtext)
{
echo "<tr>\n";
echo "<form name='notizbuch_$dbid' action='notizeintrag.php' method='post'>\n";
echo " <td><input type=text name='uhrzeit' value='$dbuhrzeit' maxlength=5></td>\n";
echo " <td><input type=text name='text' value='$dbtext' maxlength=100></td>\n";
echo " <td><input type=hidden name='datum' value='$dbdatum'>\n";
echo " <input type=hidden name='id' value='$dbid'>\n";
echo " <input type=submit name='form_loeschen' value='löschen'>\n";
echo " <input type=submit name='form_aendern' value='ändern'>\n";
echo " </td>\n";
echo "</form>\n";
echo "</tr>\n";
}
|
Die beiden 'hidden'-Felder werden nicht im Browser angezeigt, sondern dienen uns lediglich als Merkfeld. Zum einen für die Datensatznummer und zum anderen für das Tagesdatum. Ein Eintrag kann also nur innerhalb des aktuellen Tages durch Änderung der Uhrzeit verschoben werden, nicht aber auf einen anderen Tag. Die beiden 'submit'-Einträge erzeugen einen Button im Browser, mit dem die Änderungen in die Tabelle zurückgeschrieben werden können oder ganz aus der Tabelle gelöscht werden.
Fehlt uns also nur noch die Möglichkeit, auch Daten in die Tabelle hinein zu bekommen. Dazu wird ganz einfach am Ende ein leeres Formular erzeugt und mit einem passenden Button versehen:
echo "<tr>\n"; echo "<form name='notizbuch_0' action='notizeintrag.php' method='post'>\n"; echo " <td><input type=text name='uhrzeit' value='' maxlength=5></td>\n"; echo " <td><input type=text name='text' value='' maxlength=100></td>\n"; echo " <td><input type=hidden name='datum' value='$suchdatum'>\n"; echo " <input type=hidden name='id' value='0'>\n"; echo " <input type=submit name='form_neu' value='neu erfassen'>\n"; echo " </td>\n"; echo "</form>\n"; echo "</tr>\n"; |
Wenn einer der Buttons angeklickt wird, wird das Formular an uns selbst geschickt (bewirkt der Teil action='notizeintrag.php'). Man könnte hier zwar auch eine andere Datei verwenden, da aber auch bei Änderungen/Löschungen die Notizeinträge wieder am Bildschirm angezeigt werden sollen, bietet es sich geradezu an, alles in einer Datei zusammenzufassen.
Allerdings wird ein Unterscheidungsmerkmal benötigt, mit dem wir feststellen können, ob wir durch Anklicken eines Datums oder Buttons aufgerufen wurden. Eine ganz einfache Möglichkeit stellt hierbei das 'id'- Feld dar. Bei den Aktionen Neu, Bearbeiten und Löschen ist dieses immer vorhanden, während es bei der Auswahl des Tagesdatums nicht da ist. In einer zweiten Abfrage kann dann unterschieden werden, welche Aktion genau zu erfolgen hat.
/* wurde ein Formular übergeben? */
if(isset($id))
{
if(isset($form_neu)) eintrag_neu($datum,$uhrzeit,$text);
if(isset($form_aendern)) eintrag_aendern($id,$datum,$uhrzeit,$text);
if(isset($form_loeschen)) eintrag_loeschen($id);
/* zur anzeige unten wird das Datum wieder zerlegt erwartet */
/* mit substr() wird der String zerlegt und */
/* mit sprintf() evtl. führende Nullen entfernt */
$jahr = sprintf("%d",substr($datum,0,4));
$monat = sprintf("%d",substr($datum,5,2));
$tag = sprintf("%d",substr($datum,8,2));
}
|
Nach jeder dieser Aktionen soll auch wieder der aktuelle Tabelleninhalt angezeigt werden. Problematisch dabei ist jedoch, dass die Felder tag, monat und jahr nicht mehr existieren - sie werden nur vom Kalender mitgeliefert.
Eine Möglichkeit wäre nun, diese drei Felder in weiteren hidden-Einträgen der Formulare unterzubringen. Da wir aber sowieso das aktuelle Datum haben, können wir auch einfach dieses zerlegen. Zu beachten ist lediglich, dass es in amerikanischer Notation vorliegt. Also zuerst das Jahr, dann Monat und ganz rechts der Tag. Da das Datum mit führenden Nullen erzeugt wird, müssen wir noch zu einem Trick greifen, um diese wieder zu entfernen. Denn ansonsten, wird ein "09" als Oktalzahl 9 = nicht möglich/ungültig betrachtet.
Also wird der Teilstring mittels sprintf() in eine Zahl umgewandelt (%d = Dezimal). Dabei verschwinden dann die Nullen. Alternativ könnte auch abgefragt werden, ob das erste Zeichen eine Null ist und dann der String direkt manipuliert werden.
Nach diesem Ausflug fehlen uns nur noch die oben aufgeführten drei Funktionen, um neue Einträge in die Tabelle zu schreiben, vorhandene Tabelleneinträge zu verändern oder Tabelleneinträge zu löschen.
Um einen neuen Tabelleneintrag zu erzeugen, werden das Datum, die Uhrzeit
und der Text erwartet. Die 'id' wird von mySQL selbständig hochgezählt. Es
hat keine Bedeutung, was als erstes Value übergeben wird. Optional könnte
auch jedes einzelne Feld mittels 'SET
function eintrag_neu($dbdatum,$dbuhrzeit,$dbtext)
{
$result = mysql_query("INSERT INTO notizbuch VALUES(0,'$dbdatum','$dbuhrzeit','$dbtext');");
if($result)
{
/* liefert die Satz-Id, interessiert uns aber nicht weiter */
$newid = mysql_insert_id($result);
}
else
{
echo "<BR><font color='red'>EINFÜGEN WAR NICHT MÖGLICH!</font><BR>\n";
echo "Fehlerursache: " . mysql_error() . "<BR>\n";
}
}
|
Wenn ein Eintrag bereits in der Liste war, muss dieser mit REPLACE oder UPDATE bearbeitet werden. Anhand der 'id' erkennt mySQL automatisch den Satz, der geändert werden muss. Übergeben werden in diesem Fall alle Inhalte, wobei sich aber das Datum niemals ändern kann, da der Benutzer nur die Uhrzeit und den Text im Browser bearbeiten kann.
function eintrag_aendern($dbid,$dbdatum,$dbuhrzeit,$dbtext)
{
$result = mysql_query("REPLACE INTO notizbuch VALUES($dbid,'$dbdatum','$dbuhrzeit','$dbtext');");
if($result)
{
}
else
{
echo "<BR><font color='red'>ÄNDERN WAR NICHT MÖGLICH!</font><BR>\n";
echo "Fehlerursache: " . mysql_error() . "<BR>\n";
}
}
|
Das Löschen eines Satzes gestaltet sich recht einfach. Es wird nur ein eindeutiger Schlüssel benötigt. In unserem Fall ist dies wieder die 'id'.
function eintrag_loeschen($dbid)
{
$result = mysql_query("DELETE FROM notizbuch WHERE id = $dbid;");
if($result)
{
}
else
{
echo "<BR><font color='red'>LÖSCHEN WAR NICHT MÖGLICH!</font><BR>\n";
echo "Fehlerursache: " . mysql_error() . "<BR>\n";
}
}
|
In allen drei Funktionen wird im Fehlerfall ein kurzer Hinweis im Browser ausgegeben und die Fehlerursache mittels mysql_error() von mySQL abgefragt.
Damit wäre die komplette Funktionalität beschrieben.
Diese Datei ist im Browser anzugeben
Hiermit wird der linke Kalender erzeugt
Hiermit werden die rechten Eintragungen verarbeitet
Die ausgelagerte Connect-Funktion
Abschließend noch Grafiken der drei verschiedenen Amiga-Browser (Voyager 3.3 konnte ich nicht zum Offline-Betrieb überreden).
Beim Testen ist noch zu beachten, dass der Browser nicht auf seinen Cache zurückgreift, sondern die Dateien immer frisch vom Server anfordert. Bei AWeb ist unter Einstellungen/Netzwerkeinstellungen auf der Seite "Puffer" der Eintrag "überprüfe Pufferkopie" auf "immer" zu setzen. Zwar ist in jedem Header gesetzt, doch beachtet kein einziger Amiga-Browser diesen Meta-Tag.
Das hängt auch von euch, den Lesern ab. Über Zuschriften aller Art freue ich mich genauso wie Carsten.
Michael Christoph <michael@meicky-soft.de>