.
PHP-Kochrezepte für typische Anwendungen
.
Heinrich-Heine-Universität Düsseldorf Universitätsrechenzentrum

Vorbemerkung
PHP ist ein Interpreter-Programm, das auf einem WWW-Server abgelegte Web-Dokumente dynamisch, also zur Zeit der Zugriffe durch einen Client, aufbereitet. Die PHP-Dokumente enthalten i.d.R. Text und HTML-Markup wie normale - statische - HTML-Dokumente, zusätzlich aber einen Programm-Sourcecode in der PHP-Interpretersprache, der von dem PHP-Programm interpretiert und ausgeführt wird und z.B. an der Stelle seines Auftretens variable Teile einer HTML-Seite erzeugt.

Aufgrund der zahlreichen Möglichkeiten von PHP, vor allem seiner Vielzahl von Standardfunktionen, beschränken sich die Anwendungen nicht auf variable Bestandteile in Dokumenten. Genauso können Formulareingaben ausgewertet und in Dateien oder ggf. Datenbanken hinterlegt werden. Einiges davon sollen die folgenden Beispiele illustrieren. Die Beispiele sollen auch als "Kochrezepte" für eigene Anwendungen dienen - zum Verwenden und Anpassen, ohne alle Details der Interpretersprache kennen zu müssen,

Dieses Dokument hat die Version PHP 3 zum Inhalt und besteht aus einer Überarbeitung und Anpassung meiner älteren Kochrezepte für PHP 2. Für eine vollständige Dokumentation von PHP 3 sei auf die Heimatseite von PHP verwiesen oder den deutschen Mirror mit dem Online-Manual.

Voraussetzung für die Verwendung von PHP allgemein
Es gibt zwei Möglichkeiten der Nutzung von PHP für eigene Seiten:
  1. Das Interpreterprogramm php ist im cgi-bin-Verzeichnis des Servers, auf dem Ihre Seiten liegen, installiert und zugreifbar.
    Hyperlinks auf von PHP aufzubereitende Seiten sehen dann meist so aus:
    <A HREF="/cgi-bin/php/pfad/auf/meine/seite.html">
  2. Das PHP-Programm ist als Unterprogramm in den HTTP-Server integriert. Diese Alternative gibt es z.B. beim Apache-Server, bei dem PHP als optionales Modul eingebunden werden kann.
    PHP-Dokumente werden dann an einer speziellen Endung erkannt, z.B. .php3.
Im Universitätsrechenzentrum der Heinrich-Heine-Universität Düsseldorf ist die zweite Alternative beim zentralen Server www.uni-duesseldorf.de realisiert und auf dem öffentlichen (Benutzer-) Server www-public.rz.uni-duesseldorf.de. Die Dateiendung, an der der HTTP-Server die erforderliche besondere Verarbeitung erkennt. ist die oben als Beispiel genannte .php3.
... und so können Sie die Rezepte für eigene Anwendungen nutzen...
Hinweis: Die folgenden Ausführungen gelten so genau zunächst nur für diejenigen, die auf www.uni-duesseldorf.de eigene Seiten betreuen oder eine private Homepage auf www-public.rz.uni-duesseldorf.de besitzen. Vieles sollte aber so oder ähnlich auch für andere nutzbar sein, wenn die im vorhergehenden Abschnitt genannte Grundvoraussetzung erfüllt ist. In Zweifelsfällen wenden Sie sich an Ihren Webmaster!

Und hier die einzelnen Schritte:

  1. Laden Sie das passende "Rezeptbeispiel" über den Download-Button in eine lokale Datei.
  2. Jetzt können Sie Ihre Änderungen vornehmen: Im "HTML-Teil" des Dokumentes und auch im PHP-Sourcecode. Dies geht auf jeden Fall mit einem normalen Texteditor, u.U. aber auch mit einem speziellen HTML-Editor, wenn dieser einerseits den PHP-Sourcecode nicht vernichtet, nach Möglichkeit andererseits aber auch die Bearbeitung zuläßt. Beim ersten Mal sollten Sie ggf. Ihr sonst bevorzugtes Werkzeug für die Erstellung von HTML-Seiten an einer Kopie testen, in der Sie noch keine Änderungen vorgenommen haben.
  3. Speichern Sie die geänderte Datei mit einer Endung .php3 in Ihrem Bereich auf dem Server ab (evtl. mithilfe von FTP).
  4. Erst jetzt kann das Testen beginnen! Denn das, was PHP an Veränderungen vornimmt, ist erst bei dem echten Zugriff über den Server sichtbar. Der erste Abruf vom Browser aus läßt deshalb besondere Spannung aufkommen: Kommt der von mir gewünschte Effekt oder eine Fehlermeldung?
  5. Zur Fehlersuche bietet PHP 3 ein schönes Feature: Sie können Ihrer PHP-Datei als zweiten Namen den gleichen nur mit der Endung .phps statt .php3 geben. In der Unix-Shell geht das mit dem Kommando z.B.: ln test.php3 test.phps Wenn Sie diese Datei über den Browser abrufen, bekommen Sie ein Source-Listing in verschiedenen Farben, die die Suche von Syntax-Fehlern wie fehlende Anführungszeichen stark vereinfachen.
  6. Bis Übersetzungsfehler und anschließend Verarbeitungsfehler beim PHP-Sourcecode ausgemerzt sind, müssen die Schritte 2 bis 4 u.U. mehrfach iteriert werden.
Kochrezept 1 : Tagesdatum auf der Seite
Download Demonstration (in diesem Fenster) Demonstration (in neuem Fenster)
<HTML>
<HEAD><TITLE>PHP-Kochrezept 1: Tagesdatum auf der Seite</TITLE>
</HEAD>
<BODY BGCOLOR="#ffffff" TEXT="#000000" LINK="#0000ff" VLINK="#800080" ALINK="#ff0000">
<H1>PHP-Kochrezept 1: Tagesdatum auf der Seite</H1>
<? echo "Heute ist der ", Date("d.m.Y"), "; es ist ", Date("H:i:s"), " Uhr."; ?>
<HR NOSHADE SIZE=2>
<A HREF="Welcome.php3">PHP-Kochrezepte</A> von
<A HREF="/~cappel/">Bernd Cappel</A>; Nr. 1 zuletzt geändert am
<? Echo Date("d.m.Y",getlastmod()); ?>
</BODY>
</HTML>
Anmerkungen
  • Der PHP-Sourcecode steht zwischen <? und ?>; einzelne Anweisungen werden durch Semikolon abgeschlossen. Alles andere wird eins-zu-eins an den Browser übertragen und ist normalerweise HTML-Markup und Text.
  • Die echo-Anweisung von PHP gibt den Inhalt ihrer Argumente an der Stelle des Auftretens in der HTML-Source aus; Argumente können Strings in Anführungszeichen (Quotes, ") eingeschlossen sein, PHP-Variable (beginnen mit einen Dollarzeichen) oder Standardfunktionen von PHP, die einen Wert zurückgeben. Mehrere Argumente werden durch Komma getrennt.
  • Die hier benutzte Standardfunktion Date liefert als Ergebnis Datum und/oder Uhrzeit formatiert nach den Vorgaben im ersten Argument; ohne zweites Argument wird die aktuelle Zeit verwendet, ansonsten kann eine System-Zeit als ganze Zahl angegeben werden...
  • ... wie sie z.B. die Standardfunktion getlastmod zurückgibt mit der Bedeutung des letzten Änderungszeitpunkts der aktuellen PHP-Quelle.
Kochrezept 2 : Eine Seite mit bedingtem Inhalt
Download Demonstration (in diesem Fenster) Demonstration (in neuem Fenster)
<HTML>
<HEAD><TITLE>PHP-Kochrezept 2: Bedingter Inhalt</TITLE>
</HEAD>
<BODY BGCOLOR="#ffffff" TEXT="#000000" LINK="#0000ff" VLINK="#800080" ALINK="#ff0000">
<H1>PHP-Kochrezept 2: Bedingter Inhalt</H1>
Dieser Abschnitt ist immer sichtbar.
<P>
<? 
  $ip = GetEnv("REMOTE_ADDR");
  if (ereg("^134\.99\.",$ip)):
?>
Dieser Absatz ist nur sichtbar bei einem Zugriff von einer IP-Adresse,
die mit 134.99. beginnt.
<? endif; ?>
<HR NOSHADE SIZE=2>
<A HREF="Welcome.php3">PHP-Kochrezepte</A> von
<A HREF="/~cappel/">Bernd Cappel</A>; Nr. 2 zuletzt geändert am
<? Echo Date("d.m.Y",getlastmod()); ?>
</BODY>
</HTML>
Anmerkungen
  • Nicht nur PHP-Anweisungen, sondern auch der HTML-Sourcetext zwischen dem if und endif werden unterdrückt, wenn die Bedingung FALSE ergibt. Hier ist ein typischer Anwendungsfall gezeigt, der Test, ob die Anfrage aus dem lokalen Netz kommt (hier das Klasse-B-IP-Netz der Heinrich-Heine-Universität Düsseldorf mit Adressen beginnend mit 134.99.), um lokalen und auswärtigen Besuchern eine unterschiedliche Sicht einer Seite zu bieten. Wahlweise könnte vor dem endif noch ein else-Zweig folgen:
    <? else: ?>
    Inhalt nur für auswärtige Besucher.
  • Die Standardfunktion GetEnv liest den Inhalt der Umgebungsvariablen REMOTE_ADDR, die vom HTTP-Server mit der IP-Adresse des rufenden Client versorgt wird. Dies ist die sichere Methode für eine solche Art von Zugriffskontrolle über die Adresse des Anrufers, die unbedingt verwendet werden sollte, um zu verhindern, daß findige Benutzer Adressen fälschen können. Zur Demonstration des Effektes folgt unten eine Version des Beispiels, bei der die Adresse aus einer simulierten Formulareingabe gewonnen wird. In der modifizierten Quelle ist lediglich die Zeile $ip = GetEnv(...); gestrichen.
Demonstration "TRUE" in diesem Fenster in neuem Fenster
Demonstration "FALSE in diesem Fenster in neuem Fenster
Kochrezept 3 : Formulareingabedaten als Mail verschickt
Download Demonstration (in diesem Fenster) Demonstration (in neuem Fenster)
<? 
  $addr = GetEnv("REMOTE_ADDR");
  $host = GetEnv("REMOTE_HOST");
  $body = "Aufgegeben von Host " . $host . ", IP-Adresse " . $addr . "\n\n";
  if  (IsSet($Name)) { $body = $body . "Name:  " . $Name  . "\n"; }
  if (IsSet($EMail)) { $body = $body . "EMail: " . $EMail . "\n"; }
  if (IsSet($TelNr)) { $body = $body . "TelNr: " . $TelNr . "\n"; }
  $comment1 = str_replace("\015\n","\n",$comment);
  $body = $body . str_replace("\015","\n",$comment1);
  
  mail("webmaster@uni-duesseldorf.de","Briefkasten",$body);
?>
<HEAD>
<TITLE>Ihre Mitteilung</TITLE>
</HEAD>
<BODY>
<H1>Nachricht erfolgreich abgeschickt!</H1>
Vielen Dank für Ihre Nachricht!
<P>
</BODY>
Anmerkungen
Ein häufiger Anwendungsfall von Eingabeformularen in HTML ist, seinen Leserinnen und Lesern einen Weg anzubieten, Mitteilungen abzuschicken, auch wenn sie selbst keine Mail-Adresse und keinen Mail-Zugang besitzen. Wie das mit PHP leicht zu realisieren ist, zeigt dieses Beispiel.

Das Beispielformular ist dem Elektronischen Briefkasten der Universitäts- und Landesbibliothek Düsseldorf entlehnt. Die Formularseite ist ein reines HTML-Dokument; die PHP-Seite wird im ACTION-Attribut des FORM-Elementes in dieser Seite angesprochen:

<FORM ACTION="3.php3" METHOD=POST>
In der PHP-Seite 3.php3 wird aus den eingegebenen Werten eine Mail aufbereitet und abgeschickt:
  • Die Standardfunktion Mail hat drei String-Argumente: Empfängeradresse, Subject und Body (Inhalt) der Mail. Wie hier im Beispiel gezeigt, reicht es häufig, die ersten beiden fest vorzugeben. So können die von der Formularseite stammenden Mails z.B. leicht anhand ihres Subjects gefiltert werden.
  • Der Body wird hier aus den Eingaben in den verschiedenen Eingabefeldern in der Variablen $body gesammelt. Der Operator . bedeutet in PHP bei Zeichenketten die Konkatenation.
  • Der HTML-Teil der PHP-Seite enthält die Bestätigung auf den Mail-Versand.
  • Als Absenderadresse enthalten die so verschickten Mails User- und Hostname der Kennung bzw, des Rechners, unter der bzw. auf dem der HTTP-Server läuft.
Kochrezept 4 : Datensammlung über ein Formular in einer Datei
Download Demonstration (in diesem Fenster) Demonstration (in neuem Fenster)
<HTML>
<HEAD>
<TITLE>PHP-Kochrezept 4: Datenerfassung über Formular in einer Datei gesammelt
</TITLE>
</HEAD>
<BODY BGCOLOR="#ffffff" TEXT="#000000" LINK="#0000ff" VLINK="#800080" ALINK="#ff0000">
<H1>PHP-Kochrezept 4: Datenerfassung über Formular in einer Datei gesammelt</H1>

<? if (isSet($name) && ereg("[a-zA-Z]+", $name)
    && isSet($vorname) && ereg("[a-zA-Z]+", $vorname)
    && isSet($strasse) && ereg("[a-zA-Z]+", $strasse)
    && isSet($ort) && ereg("[a-zA-Z]+", $ort)) {
   $date = Date("d.m.y H:i ");
   $host = GetEnv("REMOTE_HOST");
   $data = sprintf(
    "%s %s\n\tName:\t\t%s\n\tVorname:\t%s\n\tStrasse:\t%s\n\tPLZ/Ort:\t%s %s",
    $date,$host,$name,$vorname,$strasse,$plz,$ort);
   if (IsSet($email) && ereg("[a-zA-Z]+", $email)) { 
     $data .= sprintf("\n\tEMail:\t\t%s",$email); 
   }
   $fp = fopen("/home/cappel/test.dat","a");
   fputs($fp,$data);
   fputs($fp,"\n\n");
   fclose($fp);
?>

Folgende Daten wurden aufgenommen:
<PRE>
<? Echo $data; ?>
</PRE>
<P>

<? } else { ?>

In diesem Beispiel werden natürlich keine echten Daten für einen echten
Zweck gesammelt; wenn Sie die Funktionalität testen möchten, geben Sie am
besten Phantasiedaten ein, die keinen wirklichen Personen entsprechen.
<BR>
Die Adressen werden nicht zu anderen Zwecken benutzt oder weitergegeben.<BR>
Ihre Eingaben k&ouml;nnen nur ber&uuml;cksichtigt werden, wenn Name, Vorname, Stra&szlig;e
und Ort angegeben sind.<BR>
<FORM ACTION="4.php3" METHOD=POST>
<TABLE BORDER=0>
<TR>
<TD COLSPAN="2" ALIGN=RIGHT>
Name <INPUT NAME="name" TYPE="text" SIZE="30">
Vorname <INPUT NAME="vorname" TYPE="text" SIZE="24"><P>
<TR>
<TD COLSPAN="2" ALIGN=RIGHT>
Stra&szlig;e und H-Nr.<INPUT NAME="strasse" TYPE="text" SIZE="56"><BR>
<TR>
<TD COLSPAN="2" ALIGN=RIGHT>
Plz <INPUT NAME="plz" TYPE="text" SIZE="6">
Ort <INPUT NAME="ort" TYPE="text" SIZE="51"><P>
<TR>
<TD ALIGN=RIGHT>
E-Mail <INPUT NAME="email" TYPE="text" SIZE="30"><BR>
<TR>
<TD COLSPAN="2" ALIGN=RIGHT>
<INPUT TYPE="SUBMIT" VALUE="Ab geht's!">
</TABLE>
</FORM>
<? } ?>
<BR>
<HR NOSHADE SIZE=2>
<A HREF="Welcome.php3">PHP-Kochrezepte</A> von
<A HREF="/~cappel/">Bernd Cappel</A>; Nr. 4 zuletzt geändert am
<? Echo Date("d.m.Y",getlastmod()); ?>
</BODY>
</HTML>
Anmerkungen
  • In diesem Beispiel steckt das Eingabeformular und die Verarbeitung der Eingabedaten und die Rückmeldeseite auf die Eingabe in einer php3-Quelle:
    • Der then-Zweig enthält letzteren Teil.
    • Der else-Zweig - reiner HTML-Code - besteht aus dem Eingabeformular.
    • Die Bedingung des if prüft, ob einige Variable gesetzt sind und einen "venünftigen" Wert enthalten (hier: ob sie einen Buchstaben enthalten).
  • Die Variablen $name, $vorname, $strasse, $plz, $ort und $email werden von PHP mit den eingegebenen Werten aus den Eingabefeldern des Formulars mit den entsprechenden Namen versorgt. Einem Attribut NAME="xyz" in einem INPUT-, TEXTAREA- oder SELECT-Element entspricht also eine Variable $xyz, auf die in der im ACTION-Attribut des FORM-Elementes referierten php3-Quelle zugegriffen werden kann. Damit das klappt, sollten Sie bei den Werten der Namensattribute keine Zeichen verwenden, die in PHP eine Sonderbedeutung haben, wie -, +, / etc.
  • Zum Beschreiben der Datei werden in dem Beispiel folgende Standardfunktionen verwendet:
    fopen
    zum Öffnen einer festen Datei - hier im "Append"-Modus: Textzeilen sollen hinten drangehängt werden. fopen liefert im Erfolgsfall einen File-Pointer für die weiteren Zugriffe.
    fputs
    zum Schreiben von Text in die Datei. Erstes Argument ist der File-Pointer aus dem fopen-Aufruf, zweites eine Zeichenkette. Hier werden mittels sprintf die Variablen, die die Eingabedaten enthalten, gemäß Formatvorgabe aufbereitet und in der Variablen $data zwischengespeichert. Das ist allgemein nicht notwendig, dient hier nur dazu, die erfassten Daten anzeigen zu können.
    fclose
    zum Schließen der Datei zu dem File-Pointer $fp, um sicherzustellen, daß alle Ausgaben in der Datei landen und nicht in internen Puffern stehenbleiben.
  • Der Text, der jeweils in die Datei geschrieben wird, besteht aus einer Trennzeile mit Datum und Uhrzeit sowie dem Hostnamen des Client, von dem die Anforderung kam. An dieser Zeile könnte eine Person, die die Anforderungen bearbeiten müßte, etwa nachhalten, was erledigt und was neu ist. Alle weiteren Zeilen bestehen aus Feldname, Doppelpunkt und dem eingegebenen Wert und sind außerdem mit einem Tabulatorzeichen (\t) eingerückt. Die Zeile mit der E-Mail-Adresse wird nur angefügt, wenn etwas (genauer gesagt mindestens ein Buchstabe) eingegeben wurde. Dies dient hier nur al Demonstration wie man es machen kann. U.U. ist eine solche Abfrage für viele Felder sinnvoll, evtl. aber auch für garkeines, wenn z.B. ein Import-Format für ein Datenbankprogramm erzeugt werden soll. Dafür würde es reichen, alle Variableninhalte nur durch Tabulatorzeichen (\t in der sprintf-Formatvorgabe) getrennt hintereinander zu setzen.
  • Damit das Schreiben in die Datei klappt, muß der HTTP-Server - oder genauer: die Userid, unter der dieser läuft - Schreibberechtigung für die Datei haben, also in diesem Beispiel für /home/cappel/test.dat. Für den hier unterstellten Fall, daß sich diese Datei in einem privaten Home-Verzeichnis befindet und nicht der Server-Userid gehört, sind dafür besondere Vorkehrungen erforderlich.

    Die Möglichkeit, die in jeder Unix-Server-Umgebung funktioniert, ist das Setzen eines Schreibrechts für "other":

    cd /home/cappel
    chmod o+w test.dat
    Unter Solaris ab 2.5 ist eine "Access Control List" besser, weil das Schreibrecht gezielt nur der Server-Userid (im Beispiel: www) gegeben werden kann:
    cd /home/cappel
    setfacl -m "mask:rw-,user:www:rw-" test.dat
Kochrezept 5 : Dynamische Bildverarbeitung
Download Demonstration (in diesem Fenster) Demonstration (in neuem Fenster)
<?php 
  
  Header("Content-Type: image/png");

  $image = @ImageCreatefromPng($file);
  if ($image == ""):
    $image = ImageCreate(250,30);
    $bgc = ImageColorAllocate($image,255,255,255);
    $txc = ImageColorAllocate($image,0,0,0);
    ImageFilledRectangle($image,0,0,250,30,$bgc);
    ImageString($image,3,5,5,"Fehler bei Zugriff auf $file",$txc);
    ImagePng($image);
    ImageDestroy($image);
    exit;
  endif;

  $lnc = ImageColorAllocate($image,255,255,255);
  $xmx = ImageSX($image) - 1;
  $ymx = ImageSY($image) - 1;
  ImageLine($image,0,$y,$x - 5,$y,$lnc);
  ImageLine($image,$x + 5,$y,$xmx,$y,$lnc);
  ImageLine($image,$x,0,$x,$y - 5,$lnc);
  ImageLine($image,$x,$y + 5,$x,$ymx,$lnc);
  ImagePng($image);
  ImageDestroy($image);

?>
    
Anmerkungen
Dies ist ein Beispiel für ein PHP-Programm, das keine HTML-Seite, sondern eine Grafik im PNG-Format erzeugt. Deshalb darf die PHP-Quelle auch keinen HTML-Code oder Text außerhalb der Klammerung des Skript-Codes enthalten (hier in der Variante <?php ... ?>) und die erste Ausgabe über die Funktion header muss die HTTP-Response-Header-Zeile zur Festlegung des Dokumententyps - hier image/png - sein.

Die Image-Funktionen von PHP basieren - so vorhanden in der jeweiligen Installallation - auf der GD-Bibliothek von Thomas Boutell. Diese erzeugt und verarbeitet in der aktuellen Version keine GIF-Grafiken mehr, sondern solche im JPEG- oder PNG-Format.


Bernd Cappel, zuletzt geändert am 9.9.1999