<< Inhalt >> Workshops Inhalt

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> &lt;--- ";
38   else
39     echo "<a href='kalender.php?monat=12&jahr=" . ($jahr-1) . "'>"
                                         . $monatstr[12] . "</a> &lt;--- ";
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 " ---&gt; <a href='kalender.php?monat=" . ($monat+1)
                  . "&jahr=" . $jahr . "'>" . $monatstr[$monat+1] . "</a>";
47   else
48     echo " ---&gt; <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'>&nbsp;</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'>&nbsp;</td>";
85       $tag++;
86     }
87     echo "<td align='center'>&nbsp;</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.

* 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>

<< >>