Eine einfache Präsentation mit statischen Webseiten, Bildern, Frames und ein wenig Animation kann inzwischen wahrscheinlich jedermann mit einem HTML-Editor und einer guten Clipart-Bibliothek in einigen Tagen oder gar Stunden zusammenklopfen. Aber für Seiten mit Datenbankanbindung, die etwa ein Gästebuch, einen Katalog oder ein Buchungssystem realisieren sollen, benötigt man eine Methode, um Seiten dynamisch an eine Datenbank anbinden zu können. "Data Driven Websites" ist das Schlagwort, mit dem hier Werbung gemacht wird und mit dem Microsoft und Netscape ihre Webserver und Webservererweiterungen Active Server Pages (Microsoft) und Livescript (Netscape) anpreisen. Auch Produkte von Drittherstellern wie zum Beispiel Cold Fusion von Allaire oder WebObjects von Apple/NeXT bieten ähnliche Möglichkeiten an. Der Preis für solche Pakete ist jedoch hoch: er beläuft sich auf viele tausend Mark oder man bezahlt wie bei Microsoft mit der Freiheit, seine Webplattform frei wählen zu können.
Doch die Open Source Szene zieht nach: Seit Juni 1998 ist der PHP Hypertext Preprocessor [1] in der Version 3.0 verfügbar. PHP3 ist der Nachfolger von PHP/FI, einem einfachen Hyptertext Preprocessor mit Datenbankanbindung, der von Rasmus Lerdorf entwickelt wurde. Andi Gutmans und Zeev Suraski haben die Sprache dann im Rahmen eines Universitätsprojektes stark erweitert, beschleunigt und in ihre heutige an C und Java angelehnte Form gebracht. An der Entwicklung von PHP waren jedoch wie bei Open Source Projekten üblich, sehr viele Leute in aller Welt [2] beteiligt.
Der PHP-Interpreter kann als CGI-Modul generiert werden und ist dann auf jedem Webserver einsetzbar, der CGI-Scripte ausführen kann. Diese Installationsvariante ist nicht nur sehr portabel, sondern sie erlaubt es auch, den Interpreter unabhängig vom Webserver upgraden zu können und mehrere unterschiedliche Versionen von PHP auf einem Webserver einsetzen zu können. Als CGI-Programm bringt der PHP-Interpreter jedoch nicht nur einen gewissen Overhead mit sich, sondern unterliegt auch einigen Einschränkungen sicherheitstechnischer Art. Diese Probleme treten nicht auf, wenn man den Interpreter über die Plugin-API seines Webservers als Bestandteil des Servers selbst ablaufen läßt. PHP unterstützt dabei neben dem Apache Webserver auch den fhttpd und demnächst die Plugin-APIs von Netscape und Microsoft.
Ein wesentliches Feature von PHP ist die Datenbankintegration. Dabei gelten der Geschwindigkeit und der Flexibilität des Datenbankzugriffes besonderes Augenmerk. Entsprechend werden neben ODBC-Treibern, die praktisch alle Datenbanken inzwischen anbieten, auch die native APIs einer ganzen Reihe von Datenbanken unterstützt, weil hier der Kommunikationsoverhead oft geringer ist und weil einige besondere Features dieser Datenbanken über ODBC nicht erreicht werden können. PHP kann mit Adabas-D, mSQL, MySQL [3], Oracle, Postgres, Solid, Sybase/Sybase-CT und Velocis native kommunizieren. Außerdem kann es dBase und filePro-Dateien sowie Unix DBM-Dateien lesen und schreiben und unterstützt die FreeODBC [4] und OpenLink ODBC APIs. Aber PHP ist noch darüber hinaus sehr kommunikationsfreudig: Es kann mit der GD-Bibliothek von Thomas Boutell [5] GIF-Bilder dynamisch beim Abruf erzeugen und dabei über FreeType beliebige TTF-Fonts einbinden, es kann über IMAP entfernte Mailboxen über das Web managen und es spricht außerdem fließend LDAP und SNMP, sodaß die Entwicklung von Webinterfaces für Netwerk-Managementapplikationen sehr einfach wird. Außerdem beherrscht PHP natürlich FTP und HTTP, sodaß die Einbindung und Kontrolle entfernter Webseiten in eigene Seiten einfach wird und sogenannte "Intelligent Agents" erstellt werden können, die entfernte Webseiten abholen, analysieren und Zusammenfassungen generieren oder automatische Aktionen auf den entfernten Seiten erzeugen.
Installation und Konfiguration
Nach dem Download der Quellen für die aktuelle PHP-Version vom Webserver des PHP-Projektes [1] und dem Auspacken der Quellen läßt sich eine CGI-Version des PHP-Interpreter sehr schnell durch den Aufruf des configure-Scriptes erzeugen. Dabei sind eine Reihe von Schaltern und Optionen anzugeben, die dem Script die Lage unter unterschiedlichen einzubindenden Bibliotheken mitteilen. Der Autor übersetzt seine CGI-Version von PHP für Suse Linux 5.3 mit den Optionen
./configure --with-mysql=/usr/local \
--with-pgsql=/usr \
--with-gd=/usr \
--with-dbase=yes \
--with-config-file-path=. \
--enable-debug=no \
--enable-safe-mode=no \
--enable-url-fopen-wrapper=yes \
--enable-track-vars=yes \
--enable-force-cgi-redirect
und ruft dann einfach make auf. Dabei wird eine Produktionsversion (ohne Debugcode) von PHP erzeugt, die die Datenbanken MySQL und Postgres unterstützt, dBase-Dateien lesen kann und über die GD-Bibliothek Grafiken erzeugen kann. Die Option --enable-url-fopen-wrapper aktiviert außerdem die HTTP und FTP-Downloadmöglichkeiten der Sprache und die Optionen --enable-track-vars sowie --enable-force-cgi-redirect sind für den sicheren Betrieb der Sprache als CGI-Modul notwendig.
Das resultierende Binary wird einfach in ein CGI-Verzeichnis des Webservers kopiert. Dorthin ist auch die Datei php3.ini-dist aus dem Hauptverzeichnis der PHP3-Distribution zu kopieren und nach php3.iniumzubenennen. Die Datei enthält eine Reihe von Voreinstellungen für den PHP3-Interpreter, die für die jeweilige Anwendung angepaßt werden können.
Verwendet man, wie die meisten Leute, den Apache-Webserver, sind außerdem noch zwei Zeilen in der srm.conf des Servers einzutragen, um den PHP-Support zu aktivieren:
AddHandler php-cgi .php3 Action php-cgi /cgi-bin/php
Tests
PHP-Programme werden in regulären HTML-Code mit eingebettet. Jede normale HTML-Seite ist also schon einmal ein gültiges, wenn auch sehr langweiliges PHP3-Programm. Um Code in solche Seiten einbetten zu können, muß man ihn auf eine von vier möglichen Arten in Erweiterungstags einbetten. Die empfohlene Methode und SGML-kompatible Methode besteht darin, PHP-Code in <?php ?>-Blöcke einzuschließen.
Der Bequemlichkeit halber kann man auch die verkürzte Form <? ?> verwenden. Einige HTML-Editoren erkennen diese beiden Pseudo-Tags jedoch nicht korrekt und "korrigieren" den vermeintlich fehlerhaften HTML-Code oder schieben ihn an andere Stellen innerhalb der Datei. Um auch solche Editoren nutzen zu können, ist es auch erlaubt <script language='php'> </script> zu verwenden, um PHP-Codeblöcke einzuschließen. Auf Wunsch zahlreicher Anwender von HTML-Editoren für Windows wurde ab PHP 3.0.4 außerdem die Möglichkeit geschaffen, PHP-Programme in ASP-Tags einzubetten: <% %> ist ebenfalls als Programmmarkierung erlaubt, wenn man in seiner php3.ini-Datei den Schalter asp_tags = On definiert. Außerdem kann <%= $variable %> als Kürzel für <% print $variable %> verwendet werden.
<html>
<head><title>Testseite</title></head>
<body bgcolor="#ffffff">
<?php
phpinfo(); // Generierung einer Statusseite
?>
</body>
</html>
|
![]() |
Die einfachste mögliche PHP-Datei sieht demnach aus, wie in Abbildung 1 gezeigt. Das in der Datei enthaltene HTML wird dabei so ausgegeben, wie angezeigt. PHP-Codeblöcke werden vom Interpreter ausgeschnitten und ausgeführt. Macht der Codeblock während der Ausführung irgendwelche Ausgaben, werden diese an Stelle des ausgeschnittenen Codeblocks eingesetzt. Im Beispiel oben wird der Block <?php phpinfo() ?>-Block also durch die Ausgabe der Funktion phpinfo() ersetzt.
Die Sprache PHP3 ist in der Syntax sehr eng an C, Java oder Javascript angelegt: Alle bekannten Kontrollstrukturen sind vorhanden und funktionieren sie, wie man es als Programmierer gewohnt ist. Variablen werden in PHP3 jedoch wie in einer Unix-Shell mit einem Dollarzeichen eingeleitet. Sie brauchen nicht deklariert werden und der PHP-Interpreter kümmert sich auch um die gesamte Speicherverwaltung. Neben den üblichen skalaren Datentypen Ganzzahl, Fließkommazahl und String, die nicht unterschieden zu werden brauchen, weil die Sprache Typumwandlungen nach Bedarf automatisch vornimmt, kennt PHP noch multidimensionale assoziative Arrays. Auch diese brauchen in der Größe nicht vordefiniert zu werden, sondern können einfach nach Bedarf verwendet werden.
if (bedingung) {
anweisungen
} else {
anweisungen
}
| Bedingungen |
if (bedingung): anweisungen else: anweisungen endif; | Alternative Schreibweise |
switch ($variable) {
case konstante1:
anweisungen
break;
case konstante2:
anweisungen
break;
default:
anweisungen
break;
}
| Mehrfachverzweigung |
while (bedingung) {
anweisungen
}
| While-Schleife |
while (bedingung): anweisungen endwhile; | Alternative Schreibweise |
for (startanweisung; vergleich; zählanweisung) {
anweisungen
}
| Zählschleife |
PHP3-Scripte können Parameter über die HTTP-Methods GET und POST erhalten und haben auch Zugriff auf Cookies. Beim Start des Scriptes werden die Parameter automatisch importiert und stehen in den gleichnamigen Variablen zur Verfügung: Wird ein Script also unter der URL /test2.php3?name=Kris&host=valiant aufgerufen, stehen dem Script die Variablen $name und $host mit den Werten Kris und valiant vorinitialisiert zur Verfügung. Ebenso werden POST-Parameter und Cookies importiert.
Wem diese Art der unkontrollierten Variablenvorbelegung sicherheitstechnisch zu aufregend ist, der kann sie über die Konfigurationsdirektive gpc_order in der php3.ini-Datei kontrollieren. gpc_order=gpc, der Default, bewirkt, daß beim Start des Scriptes zunächst alle GET-Parameter importiert werden, danach die POST-Parameter und als letztes alle Cookies. Durch Vertauschen der Buchstaben kann man die Importreihenfolge verändern, durch Weglassen von Kennbuchstaben kann man den Import aus einzelnen Datenquellen abschalten. Über die assoziativen Felder $HTTP_GET_VARS, $HTTP_POST_VARS und$HTTP_COOKIE_VARS, die in jedem Fall mit den Name-Wert-Paaren der entsprechenden Scriptparameter belegt werden, haben solche Scripte dennoch Zugriff auf alle Parameter und zugleich mehr Kontrolle darüber, welche Werte wann und wie den Programmablauf beeinflussen. Abbildung 3 zeigt ein Script, das die $HTTP_GET_VARS durchliest.
<html>
<head><title>Auslesen der Parameter</title></head>
<body bgcolor="#ffffff">
<?php
printf("<h1>Alle GET-Parameter</h1>\n");
if ( isset($HTTP_GET_VARS)) // Teste, ob überhaupt Parameter vorhanden sind.
{
reset($HTTP_GET_VARS); // Beginne am Anfang des Feldes
// und gehe mit each() alle Feldelemente durch.
while(list($k, $v) = each($HTTP_GET_VARS)) {
// $k ist der Key, $v der Value...
printf("Name: %s Wert: %s<br>\n", $k, $v);
}
}
// Gezielter Zugriff auf ein einzelnes Element des Feldes.
printf("Der Parameter name hat den Wert %s<br>\n",
$HTTP_GET_VARS["name"]);
?>
</body>
</html>
|
![]() |
Das Script enthält ein interessantes Konstrukt, daß man in PHP sehr häufig findet. Es handelt ist um die Redewendung reset ($arrayname); while (list($k, $v) = each($arrayname)) { ... }. Diese Anweisung liest das Array $arrayname elementweise durch. Der Index des aktuellen Elementes steht dabei in der Variablen $k zur Verfügung, sein Wert in $v.
In PHP sind die Elemente eines assoziativen Arrays untereinander durch Zeiger verbunden, sodaß eine Reihenfolge erhalten bleibt, auch wenn es sich eigentlich um einen Hash handelt, der bei der Ablage der Elemente im Speicher keine Reihenfolge definiert. Außerdem hat jedes Array intern einen Zeiger auf ein aktuelles Element, den man durch diese Liste bewegen kann. Die Anweisung reset($arrayname)stellt diesen internen Zeiger auf den Anfang des Arrays zurück. Die Funktion each($arrayname) liefert nun den Index und den Wert des aktuellen Elementes als Feld mit zwei Elementen zurück und schiebt den internen Zeiger aktuelle Element vorwärts. list($k, $v) wiederum erzeugt aus den beiden Variablen $k und $v ein weiteres Array mit zwei Elementen, aber in der Form von LVALUES, also von Zeigern auf Speicherplätze, denen man Werte zuweisen kann. Der erste von each() zurückgegebene Wert wird also in $k abgespeichert, der zweite von each() zurückgegebene Wert in $v.
Zugriff auf Datenbanken
Über eingebaute Abfragefunktionen ist der Zugriff auf Datenbanken in PHP leicht zu realisieren. Das Beispielprogramm in Abbildung 4 zeigt ein PHP-Script, das auf eine MySQL-Datenbank zugreift.
<html>
<?php
// Verbindung zur Datenbank auf localhost als
// User kris ohne Paßwort.
$link = mysql_connect("localhost", "kris", "");
// Auswahl der zu verwendenden Datenbank auf dem Server
$query = "use beispiel";
if (!mysql_query($query, $link))
die("Datenbank beispiel existiert nicht.<br>\n");
// Auslesen der Tabelle auth_users in dieser Datenbank
$query = "select username, password, perms from auth_users";
$res = mysql_query($query, $link);
if (!$res)
die("Anfrage $query scheitert.<br>\n");
// Bestimme Größe des Ergebnisses
$rows = mysql_num_rows($res);
$cols = mysql_num_fields($res);
printf("Anfrage ergibt %d Zeilen zu %d Spalten.<br>\n", $rows, $cols);
// Durchlesen des Ergebnisses
while($d = mysql_fetch_array($res)) {
// $d ist ein Array aus Spaltenname, aktuellem Wert
reset($d);
while(list($k, $v) = each($d)) {
printf("%s = %s, ", $k, $v);
}
printf("<br>\n");
}
?>
|
Um eine Datenbankabfrage durchführen zu können, muß man zunächst einmal eine Verbindung zur Datenquelle herstellen. Im Beispiel wird die native API einer Datenbank (hier: MySQL) verwendet, aber der Zugriff über ODBC folgt im wesentlichen denselben Regeln. mysql_connect() stellt die Verbindung zum Datenbankserver her. Dabei muß dem Kommando der Name des Serverhosts und ein Username/Paßwort-Paar mitgegeben werden. Das Resultat ist, wenn alles stimmt, die ID eines Datenbank-Links, über das man weitere Kommandos senden kann.
In der Regel wird man auf einem Datenbankserver eine ganze Reihe von Datenbanken haben. Das Beispielscript oben wählt zunächst mit dem use-Kommando eine Datenbank aus, indem es mit Hilfe von mysql_query() ein entsprechendes Kommando über das Datenbank-Link sendet. Danach wird ein weiteres Kommando, ein SQL-Select-Kommando über das Link an den Datenbankserver abgeschickt. Weitere API-Funktionen erlauben es dann, die Breite und Höhe der Ergebnistabelle zu bestimmen und auszugeben.
Schließlich wird die API-Funktion mysql_fetch_array() verwendet, um nacheinander jeweils eine Zeile des Ergebnisses einzulesen und dem PHP-Script als assoziatives Array $d zur Verfügung zu stellen. Die Funktion liefert jeden Spaltenwert der aktuellen Zeile zweimal: Einmal über die Spaltennummer (0,1,...) indiziert und einmal über den Spaltennamen (username, password, ...) indiziert. Innerhalb der Schleife kann man auf Werte in der aktuellen Zeile entweder über $d[0] bzw. $d["username"] zugreifen, oder man zählt die Elemente des Feldes $d wieder auf die in PHP übliche Weise auf.
Es ist ein leichtes, die Ausgabe so umzustellen, daß statt einfacher <br>-Tags auch komplizierteres HTML (etwa eine Tabelle) erzeugt wird.
Kekse und andere Headerzeilen
Über die Header()-Funktion kann PHP HTTP-Headerzeilen generieren. Dies ist sehr nützlich, weil man auf diese Weise CGI-Redirects oder Cache-Control-Zeilen erzeugen kann. Gerade letzteres ist bei Seiten mit dynamisch generiertem Inhalt immens wichtig.
Dabei ist es wichtig zu wissen, daß man die header()-Funktion in PHP nur dann erfolgreich einsetzen kann, wenn man den entsprechenden PHP-Code unmittelbar an den Anfang der Seite schreibt. PHP hält die Erzeugung der Ausgabe solange zurück, wie noch kein HTML auf der Seite enthalten ist. In dieser Zeit können mit header() beliebig viele Headerzeilen generiert werden. Sobald jedoch das erste HTML auf der Seite angetroffen wird, gibt PHP jedoch die angesammelten Headerzeilen sowie bei Bedarf auch seinen Standardheader Content-Type: text/html aus. Danach sind keine weiteren header()-Aufrufe mehr möglich.
<?php
header("Expires: 0"); // Netscape Browser Cache
header("Pragma: no-cache"); // HTTP/1.0 Cache
// HTTP/1.1 Cache
header("Cache-Control: no-cache");
// Link aufbauen
$link = mysql_connect("localhost", "kris", "");
mysql_query("use beispiel", $link);
// Zähler hochzählen
$query = sprintf("update page_counter set counter = counter +1 where pagename = '%s'",
$PHP_SELF);
$res = mysql_query($query, $link);
$success = mysql_affected_rows($link);
// Wenn der Zähler noch nicht existierte, anlegen.
if (!$success) {
$query = sprintf("insert into page_counter ( pagename, counter) values('%s', '1')",
$PHP_SELF);
mysql_query($query, $link);
}
// Zählerstand abfragen
$query = sprintf("select counter from page_counter where pagename = '%s'",
$PHP_SELF);
$res = mysql_query($query, $link);
$d = mysql_fetch_array($res);
$counter = $d["counter"];
?>
<html>
<body bgcolor="#ffffff">
<h1>Seitenzähler</h1>
Diese Seite wurde <?php print $counter ?> mal aufgerufen.
</body>
</html>
|
kris@valiant:/home/kris > mysql beispiel
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 29 to server version: 3.21.33
Type 'help' for help.
mysql> create table page_counter (
-> pagename varchar(127) not null,
-> counter integer,
-> primary key (pagename)
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> describe page_counter;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| pagename | varchar(127) | | PRI | | |
| counter | int(11) | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> quit
|
In Abbildung 5 ist ein Script zu sehen, das seine Ausgabe als variabel und nicht in Caches zu speichern markiert. Es generiert zu diesem Zweck drei Headerzeilen, Expires, Pragma und Cache-Control. Die erste Headerzeile bewirkt, daß Netscape die Seite nicht in seinem internen Browsercache hinterlegt, sondern bei jedem Abruf neu holt. Die zweite Headerzeile teilt HTTP/1.0-Caches auf dem Weg zwischen den Server und dem Browser mit, daß die Seite nicht gecached werden darf, während die dritte Zeile dies den unterschiedlichen Sorten von HTTP/1.1-Caches klarmacht.
Der eigentliche Code der Seite ist ebenfalls interessant: In einer Datenbanktabelle page_counter mit den beiden Spalten pagename (Ein String von bis zu 127 Zeichen Länge) und counter (eine ganze Zahl) werden die Abrufzahlen von Webseiten hinterlegt (siehe Abbildung 5b). Der Name der abgerufenen Seite wird dabei über die PHP-Einbauvariable $PHP_SELF bestimmt. Das Script versucht zunächst, mit Hilfe einer SQL-Update Anweisung den Zähler für die betreffende Seite zu erhöhen. Dies gelingt in der Regel, nur beim ersten Abruf der Seite scheitert dies, weil noch kein Zähler für diese Seite existiert. Über die Funktion mysql_affected_rows() kann man feststellen, wieviele Zeilen von der Update-Anweisung bearbeitet wurden. Nach Konstruktion ist dies entweder eine Zeile, wenn der Zähler für die betreffende Seite schon existiert oder keine Zeile, wenn der Zähler für die Seite noch nicht existiert. In diesem Fall muß eine SQL-Insert Anweisung nachgeschoben werden, die den Zähler anlegt. Schließlich kann der aktuelle Zählerstand abgefragt und in der Variablen $counter zur Verfügung gestellt werden.
Im wirklichen Leben wird man diese Codezeilen natürlich nicht auf jede seiner Seiten setzen wollen. Stattdessen wird man sich eine Include-Datei definieren, die eine Funktion count_page() enthält, die den Seitenzähler weiterstellt. Außerdem wird die Include-Datei auch eine Funktion insert_page_counter() enthalten, die den aktuellen Zählerstand einer beliebigen Seite ausliest und automatisch count_page() aufrufen. Abbildung 6 zeigt den modifizierten Code.
<?php
function count_page() {
global $PHP_SELF;
header("Expires: 0");
header("Pragma: no-cache");
header("Cache-Control: no-cache");
$link = mysql_connect("localhost", "kris", "");
mysql_query("use beispiel", $link);
$query = sprintf("update page_counter set counter = counter +1 where pagename = '%s'",
$PHP_SELF);
$res = mysql_query($query, $link);
$success = mysql_affected_rows($link);
if (!$success) {
$query = sprintf("insert into page_counter ( pagename, counter) values('%s', '1')",
$PHP_SELF);
mysql_query($query, $link);
}
}
function insert_page_counter($pagename = "") {
global $PHP_SELF;
if ($pagename == "")
$pagename = $PHP_SELF;
$link = mysql_connect("localhost", "kris", "");
mysql_query("use beispiel", $link);
$query = sprintf("select counter from page_counter where pagename = '%s'",
$pagename);
$res = mysql_query($query, $link);
$d = mysql_fetch_array($res);
return $d["counter"];
}
// count_page einmal aufrufen...
count_page();
|
Die Include-Datei sollte in einem gesonderten Verzeichnis abgelegt werden, das nicht unterhalb der DocumentRoot des Webservers liegt und das auch kein CGI-Verzeichnis ist. Es bietet sich also eine Struktur wie die folgende für den Webserver an:
/ --- home --- www --- www.koehntopp.de --+-- pages
|
+-- cgi
|
+-- php
Dabei ist /home/www/www.koehntopp.de/ das Basisverzeichnis des Webservers. In ihm befinden sich das Unterverzeichnis pages, das die DocumentRoot des Webservers darstellt, das Unterverzeichnis cgi, in dem sich der PHP-Interpreter und die php3.ini befinden und das Unterverzeichnis php, in dem die PHP-Includes abgelegt werden sollen.
In der php3.ini trägt man nun in der Zeile include_path=den Pfadnamen PHP-Includeverzeichnisses ein. In der include_path=-Zeile können mehrere Verzeichnisse angegeben werden, deren Namen mit einem Doppelpunkt (in Unix) oder einem Semikolon (in Windows) getrennt werden müssen.
Nun kann dieser Code den Anweisungen require("count.inc") oder include("count.inc") eingebunden werden. Er wird an der Stelle in die aktuelle Seite eingefügt, an der die require() bzw. include()-Anweisung steht. require() und include() unterscheiden sich nicht in der Wirkung, wohl aber in der Effizienz der Ausfühung: require() ist schneller als include(), wird aber unbedingt ausgeführt, auch dann, wenn die Anweisung zum Beispiel in einem if-Block steht und der eingebundene Code also niemals ausgeführt werden würde. Entsprechend sollte man require() verwenden, wenn man statische Einbindungen vornehmen möchte, etwa für Vorspänne oder immer benötigte Bibliotheksfunktionen und include(), wenn man bedingte (dynamische) Einbindungen vornehmen möchte, z.B. mit variablen Dateinamen oder durch ein if() geschützt.
Anders als in C werden in PHP Funktionsdefinitionen mit dem Schlüsselwort function eingeleitet. Danach folgt der Name der Funktion und eine Parameterliste. Für alle Parameter kann optional ein Defaultwert angegeben werden (siehe die Definition von insert_page_counter() in Abbildung 6. Der Rückgabewert der Funktion kann, wenn einer berechnet werden soll, wie in C mit einem return zurückgegeben werden.
<?php require("count.inc") ?>
<html>
<body bgcolor="#ffffff">
<h1>Seite mit Zähler</h1>
Diese Seite wurde bisher <?php insert_page_counter() ?> mal
aufgerufen.<p>
Die Seite <tt>/blafasel.html</tt> wurde bisher <?php
insert_page_counter("/blafasel.html") ?> mal aufgerufen.
</body>
</html>
|
Abbildung 7 zeigt den Seitenzähler in einer Beispielanwendung. An Stelle der require()-Anweisung muß man sich den in count.inc enthaltenen Code hindenken, d.h. dort sieht der PHP-Interpreter die Definitionen der Funktionen count_page() und insert_page_counter() sowieso einen Aufruf von count_page().
Auf der Seite wird dann insert_page_counter() einmal ohne Parameter und einmal mit dem Namen einer anderen Seite als Parameter aufgerufen. Dies ist möglich, weil bei der Definition der Funktion insert_page_counter() ein Default-Wert für den Parameter $pagename angegeben wurde: Läßt man den Parameter weg, wird $pagecounter als leer angenommen und weiter unten in der Funktion durch den Namen der aktuellen Seite, $PHP_SELF, ersetzt. In diesem Fall gibt die Funktion den Zählerstand für die aktuelle Seite zurück. Gibt man dagegeben den Namen einer anderen Seite an, wird der Zählerstand dieser Seite zurückgegeben. Dabei ist lediglich zu beachten, daß man den Seitennamen genauso wie $PHP_SELF angibt, also mit führendem Slash und passender Groß- und Kleinschreibung.
Ausblick
Wenn man länger mit PHP arbeitet, wird man sich bald eine Reihe von Include-Dateien mit unverzichtbaren Funktionen zulegen, also eine Bibliothek mit immer wieder gebrauchtem Code anlegen. PHP uterstützt die Bildung von Bibliotheken durch einfache objektorientierte Features, die die Verwaltung des globalen Namensraumes vereinfachen. Dies wird am Beispiel einer kleinen Datenbank-Zugriffsklasse DB_Sql erläutert werden.
Außerdem kann man mit PHP dynamisch Bilder erzeugen. Mit der DB_Sql-Klasse werden wir die Zugriffstatistik einer Website abrufen und ein Abrufdiagramm berechnen, das bei jedem Abruf die aktuellen Werte enthält. Dabei werden wir uns auch näher mit den Feldtypen in PHP auseinandersetzen müssen.


Keine Kommentare:
Kommentar veröffentlichen