2. Workshop: Monatskalender in PHP (von Michael Christoph)
PHP ist eine moderne Internetskriptsprache (eine Mischung aus Basic, C und
Perl) und liegt auch in der aktuellen Version 4.0 für den Amiga vor.
Da es sich im Gegensatz zu JavaScript um eine serverseitige
Programmiersprache handelt, ist ein laufender Webserver zwingende
Voraussetzung für das Erstellen, Testen und Laufen lassen von PHP-Skripten.
Auch diese Aufgabe meistert der Amiga mit dem Apache-Webserver souverän.
* DIE INSTALLATIONSANWEISUNGEN GIBT ES WOANDERS
Soviel als Einleitung zu PHP. Grundlagen und Installationsanleitungen
finden sich im Amiga-Magazin 08/2001 bzw. auch online unter
http://www.meicky-soft.de/amiga-magazin/mysql.html
* EIN PAAR EINLEITENDE WORTE
Ich will hier keinen Einstiegskurs in die PHP-Programmierung beginnen, wer
aber bereits (in anderen Sprachen) programmieren kann und sich für PHP
interessiert, sollte trotzdem gut zurechtkommen.
Und im Gegensatz zu anderen Publikationen und Vorgehensweisen werde ich
sofort mit dem fertigen Beispiel beginnen, das dann Schritt für Schritt
genauer betrachtet wird. Dabei handelt es sich auch schon um ein sehr
praktisches Beispiel und nicht die in Bücher oft zu findenden dreizeiligen
Kurzbeispiele. Trotzdem soll dieses Beispiel lediglich als Grundlage
dienen, das jeder nach seinen Wünschen noch weiter ausbauen
kann.
* DAS BEISPIEL
Screenshot:
1 <?php
2 /* kalender.php */
3 /* 01.08.2002, Michael Christoph <michael2meicky-soft.de> */
4
5
6 /* Hilfsfunktion zur Ermittlung von Feiertagen */
7 function isFeiertag($m,$d,$y)
8 {
9 /* es wird nur der Sonntag als Feiertag erkannt */
10 if( date("w",mktime(1,1,1,$m,$d,$y)) == 0 )
11 return 'red';
12 else
13 return 'black';
14 }
15
16
17 /* erstes Element leer, damit Monat 1 = Januar ist */
18 $monatstr = array("", "Januar", "Februar", "März", "April", "Mai",
"Juni", "Juli", "August", "September", "Oktober",
"November", "Dezember");
19
20 /* beim ersten Aufruf den heutigen Monat und Jahr anzeigen */
21 if(!(isset($jahr)))
22 {
23 $jahr = date("Y",time());
24 $monat = date("n",time());
25 }
26 $tag = 1;
27 $timestamp = mktime(1,1,1,$monat,$tag,$jahr);
28
29 /* das Kalenderblatt als Tabelle ausgeben */
30 echo "<center><br><br>";
31 echo "<table width='800' border='0'>";
32 echo "<tr>";
33 echo "<td align='center' valign='top'>";
34
35 /* Link für vorherigen Monat erzeugen */
36 if($monat > 1)
37 echo "<a href='kalender.php?monat=" . ($monat-1) . "&jahr="
. $jahr . "'>" . $monatstr[$monat-1] . "</a> <--- ";
38 else
39 echo "<a href='kalender.php?monat=12&jahr=" . ($jahr-1) . "'>"
. $monatstr[12] . "</a> <--- ";
40
41 /* das aktuelle Monat dazwischen mit Jahreszahl ausgeben */
42 echo " <font size='5' face='tahoma'>" . $monatstr[$monat]
. " $jahr</font> ";
43
44 /* Link für folgenden Monat erzeugen */
45 if($monat < 12)
46 echo " ---> <a href='kalender.php?monat=" . ($monat+1)
. "&jahr=" . $jahr . "'>" . $monatstr[$monat+1] . "</a>";
47 else
48 echo " ---> <a href='kalender.php?monat=1&jahr=" . ($jahr+1)
. "'>" . $monatstr[1] . "</a>";
49
50 echo "<table width='150' border='1'>";
51
52 /* als Überschrift die Wochentage eintragen */
53 echo "<th align='center' width='20'>Mo</th>";
54 echo "<th align='center' width='20'>Di</th>";
55 echo "<th align='center' width='20'>Mi</th>";
56 echo "<th align='center' width='20'>Do</th>";
57 echo "<th align='center' width='20'>Fr</th>";
58 echo "<th align='center' width='20'>Sa</th>";
59 echo "<th align='center' width='20'><font color='red'>So</font></th>";
60 echo "<tr>";
61
62 /* erst mal einrücken bis zum Wochentag des 1. */
63 $wochentag = date("w",$timestamp);
64 if($wochentag == 0) $wochentag = 7; /* 0=Sonntag */
65 for($i=1; $i<$wochentag; $i++)
66 {
67 echo "<td align='center'> </td>";
68 }
69
70 /* dann alle Tage des Monats ausgeben */
71 while(checkdate($monat,$tag,$jahr))
72 {
73 echo "<td align='center'><font color='"
. isFeiertag($monat,$tag,$jahr) . "'>$tag</font></td>";
74 /* am Sonntag ist die Zeile zu Ende und eine neue wird begonnen */
75 if(isFeiertag($monat,$tag,$jahr) == "red") { echo "</tr><tr>"; }
76 $tag++;
77 }
78
79 /* noch auffüllen bis zum Sonntag */
80 if(! (isFeiertag($monat,$tag-1,$jahr) == "red"))
81 {
82 while(! (isFeiertag($monat,$tag,$jahr) == "red"))
83 {
84 echo "<td align='center'> </td>";
85 $tag++;
86 }
87 echo "<td align='center'> </td>";
88 }
89
90 echo "</tr>";
91 echo "</table>";
92 echo "</td>";
93
94 echo "</tr>";
95 echo "</table>";
96 echo "</center>";
97
98 ?>
* ERKLÄRUNG ZUM BEISPIEL
Das Beispiel ist lediglich zur besseren Orientierung zeilenweise
nummeriert. Die Zahlen sind nicht mit einzugeben! Zeilen ohne Nummer sind
lediglich zur besseren Lesbarkeit umgebrochen worden und einzeilig.
Speichert es unter dem Namen "kalender.php" ab. Wichtig ist, als Endung
".php" oder ".php3" oder ".php4" oder ".phps" zu verwenden, um Apache
mitzuteilen, dass der Textinhalt erst noch verarbeitet werden muss, bevor
er an den Browser gesendet wird. Dabei hängt es von der Apache-
Konfiguration ab, welche Endungen erkannt und benutzt werden können. Lokal
kann dies in Apache:conf/httpd.conf eingetragen werden, ansonsten ist beim
ISP nachzufragen.
PHP kann innerhalb eines HTML-Codes eingebettet werden, aber auch
umgekehrt, HTML-Anweisungen können von PHP-Code erzeugt werden.
Mittels "<?php" oder auch kurz "<?" wird der Begin eines PHP-Blocks
gekennzeichnet. Entsprechend ist "?>" als Endmarkierung zu verwenden.
Außerhalb dieses Blockes kann ganz normaler HTML-Code geschrieben
werden.
Das ganze Programm setzt sich lediglich aus ein paar unterschiedlichen PHP-
Funktionen zusammen. Diese werde ich hier nur kurz vorstellen.
Heutzutage gibt es eine große Anzahl an PHP-Literatur. "GoTo PHP 4" aus dem
Addison-Wesley-Verlag (590 Seiten, 39,95 EURO mit CD) sei hier als
empfehlenswertes Beispiel genannt. Ein sehr umfangreiches (über 7 MByte
großen) PHP-Handbuch ist unter "http://www.php.net/manual/de/" zu finden.
- isset
dient zur Überprüfung, ob eine Variable gesetzt ist oder nicht.
Wird ein PHP-Skript aufgerufen, stehen automatisch alle Aufrufoptionen
der URL-Zeile als benannte Variablen zur Verfügung.
Der Aufruf "http://localhost/kalender.php?monat=8&jahr=2002"
erzeugt die beiden Variablen $monat und $jahr (Variablen werden
durch ein vorangestelltes Dollarzeichen gekennzeichnet) und setzt
sie auf die Werte 8 und 2002. Wird nur die Anweisung
"http://localhost/kalender.php" aufgerufen, sind beide Variablen
nicht vorhanden.
- echo
ist wohl die wichtigste Funktion und erlaubt neben printf
die Ausgabe von Text und HTML-Code an den aufrufenden Web-Browser.
- mktime
erlaubt die Erstellung eines sogenannten Timestamps. Der Timestamp
kann Datum und Uhrzeit als Integerzahl repräsentieren. Zu beachten
ist die Reihenfolge der Parameter: Stunde,Minute,Sekunde,Monat,Tag,Jahr!
- date
erlaubt die Ausgabe eines Timestamps in benutzerverständlicher Form.
Anhand Platzhalterzeichen kann sehr flexibel das Ausgabeformat festgelegt
werden ("w" z.B. für den Wochentag)
- checkdate
dient zur Überprüfung eines Datums auf Gültigkeit. Zu beachten ist
die Reihenfolge der Parameter: Monat,Tag,Jahr!
- array
erlaubt das Erstellen von Arrays. Dabei können beliebige Datentypen
in einem Array gemischt werden (also z.B. Zahlen und Strings).
Auch assoziative Arrays sind möglich und werden in der Form
"name => michael" geschrieben.
- for
Zählschleife, wie in C
- while
Schleife mit Kopfbedingung, wie in C
- isFeiertag
eigene Hilfsfunktion
* DAS BEISPIEL WIRD BETRACHTET
Das Beispiel beginnt eigentlich in Zeile 18, da vorher lediglich eine neue
Funktion bekannt gegeben wird. Es können auch mehr Funktionen sein bzw.
diese aus externen Dateien "includiert" werden.
In Zeile 18 wird lediglich ein Array erzeugt, das die Monatsnamen in
deutscher Schreibweise enthält. Die Funktion date() liefert zwar mittels
des Platzhaltersymbols "F" auch den Monatsnamen, allerdings mit englischer
Bezeichnung. Da PHP (wie auch C) bei 0 zu zählen beginnt, die Monate aber
mit 1 beginnen, wird das erste Element des Arrays leer gelassen.
Die Zeilen 21 bis 25 dienen dazu, festzustellen, ob das Skript mit oder
ohne Parameter aufgerufen wurde. Ohne Parameter (also
"http://localhost/kalender.php" allein) werden der heutige Monat und Jahr
als Startwerte verwendet. Ansonsten wird dieser Programmteil gar nicht
ausgeführt.
Zeile 26 setzt den Tageszähler auf 1. Er wird später bei der Ausgabe
jeweils ums eins erhöht, bis zum Monatsletzten.
Weiter geht es dann in der Zeile 27, in der aus dem Datum (und einer für
unser Beispiel irrelevanten Uhrzeit 1 Uhr, 1 Minute und 1 Sekunde) ein
Timestamp zur weiteren Verarbeitung generiert wird.
Die Zeilen 30 bis 33 beginnen dann mit der Erzeugung einer HTML-Tabelle.
In den Zeilen 36 bis 39 wird ein HTML-Link erzeugt, bei dessen Auswahl der
vorhergehende Monat im Browser angezeigt wird. Falls der aktuelle Monat
noch nicht Januar ist, wird der Link für einen Monat verringert erzeugt,
ansonsten für Dezember des vorhergehenden Jahres.
Zeile 42 schreibt zwischen die beiden Links den Namen des aktuellen Monats
mit Jahreszahl in einer größeren Schrift.
Zeilen 45 bis 48 erzeugen entsprechend einen Link für den folgenden Monat.
Falls noch nicht Dezember ist, für den nächsten Monat, sonst für Januar des
darauffolgenden Jahres.
Falls das Monatsarray (Zeile 18) sofort mit "Januar" als ersten Eintrag
begonnen worden wäre, hätte für die vorangegangenen Zeilen 36 bis 48
jeweils als Index [$monat-1] geschrieben werden müssen. Deutlich besser zu
lesen ist es allerdings ohne die -1, und auch die Fehleranfälligkeit wird
verringert.
Die Zeilen 53 bis 59 sorgen dann dafür, dass als Tabellenüberschriften die
Wochentage verwendet werden. Dabei wird der Sonntag rot geschrieben (wie
alle späteren Sonntage im Kalender auch).
In Zeile 63 wird ermittelt, auf welchen Wochentag der Monatserste fällt.
Das Ergebnis ist ein Zahlenwert von 0 (=Sonntag) bis 6 (=Samstag). Falls es
sich um einen Sonntag handelt, erhöhen wir in Zeile 64 den Wert auf 7. In
den folgenden Zeilen 65 bis 68 werden nämlich Wochentage-1 leere Tabellen-
Felder erzeugt.
Die eigentliche Ausgabe des Kalenders erfolgt dann in den Zeilen 71 bis 77.
Diese Schleife wird solange durchlaufen, bis das Datum nicht mehr gültig
ist. Dadurch werden alle Tage des Monats als einzelne Zellen ausgegeben.
Zeile 73 ist dafür zuständig, dass die Tage, die auf einen Sonntag fallen,
in rot ausgegeben werden.
Zeile 75 hingegen beginnt eine neue Reihe, wenn der Sonntag ausgegeben
wurde. Zeile 76 zählt lediglich den Tageszähler um eins hoch.
In Zeile 80 wird geprüft, ob das zuletzt ausgegebene Datum ein Sonntag war.
Ist dies nicht der Fall, werden die Zeilen 82 bis 87 ausgeführt, die dafür
sorgen, dass noch entsprechend viele leere Zellen erzeugt werden, um die
aktuelle Reihe zu vervollständigen.
Die Zeilen 90 bis 96 dienen dann lediglich noch zum Abschließen der
Tabellenanweisungen.
Damit sollte das Beispiel doch ausführlich genug beschrieben worden sein,
damit es jeder Interessierte leicht nachvollziehen und vor allem verstehen
kann.
Lediglich die Zeilen 7 bis 14 muss ich noch nachreichen. Hierbei handelt es
sich um eine Hilfsfunktion, mit der festgestellt werden soll, ob das
übergebene Datum ein Feiertag ist. Bisher beschränkt sich die Funktion
allerdings darauf, den Sonntag zu erkennen. Dazu wird in Zeile 10 das Datum
in einen Timestamp konvertiert und mittels der Date-Funktion der Wochentag
ermittelt. Liefert diese 0 zurück, ist es ein Sonntag, und es wird als
Rückgabe "red" geliefert, ansonsten "black". Dieser String wird direkt als
Farbkodierung für die HTML-Font-Anweisung verwendet.
* FORTSETZUNG ERWÜNSCHT?
Wenn seitens der Leser Interesse besteht, bin ich gerne bereit, dieses
Beispiel weiter auszubauen und in Verbindung mit einer mySQL-Datenbank mit
dynamischen Inhalten zu ergänzen, beispielsweise für einen Terminkalender.
Schreibt uns, was euch interessiert!
Michael Christoph <michael@meicky-soft.de>
|