Dynamische Websites
von Jochen Lillich (Jochen.Lillich@dynamis.de)

Linux eignet sich bekanntermaßen sehr gut als Web-Plattform. Dies beschränkt sich jedoch bei weitem nicht auf das "Servieren" statischer Seiten. Heutzutage sind es dynamisch generierte Seiten, die aktuelle Informationen, möglichst in Echtzeit, aus einer oder mehreren Datenquellen bereitstellen, die den größten Erfolg haben. Wie man so eine Website realisieren kann, zeigt dieser Artikel auf.

Inhalt

Dynamische Websites
    Definition
    Vorteile
Grundlagen dynamischer Websites
    Datenbank
    Serverside Skripting
Entwicklung dynamischer Seiten mit PHP3
    Die Skriptsprache PHP3
    Grundlagen der PHP-Programmierung
        Variablen
        Funktionen
        Ausdrücke
        Kontrollstrukturen
    Zugriff auf Datenbanken
    Integration von HTML und PHP
    Ein Praxisbeispiel
    Weitere Anwendungsmöglichkeiten
        Session-Management
        Authentifizierung
        Persistenz
Ausblick
    Beispiele für mit PHP3 erstellte Websites
    Zend, die optimierte PHP-Engine

Dynamische Websites

Definition

Bei Websites spricht man von statischen Inhalten, wenn die Informationen fest in den HTML-Dateien verankert sind, die dem Besucher übermittelt werden. Bei dynamischen Websites hingegen werden die HTML-Seiten aus verschiedenen Quellen erzeugt. Dies kann regelmäßig erfolgen (zB täglich oder stündlich) oder individuell bei jeder Seitenanforderung.

Mögliche Datenquellen sind Datenbanken, Warenwirtschaftssysteme, HTML-Schablonen, XML-Dateien usw.

Vorteile

Trennung von Layout und Inhalt

Da dynamische Web-Seiten aus verschiedenen Informationsquellen erzeugt werden, ist eine Trennung von Layout und Inhalt möglich. Die bereitzustellenden Rohinformationen sind meist strukturiert in Form von Datenbanken hinterlegt und werden zum Beispiel mit HTML-Schablonen gemischt, um im Browser darstellbare Seiten zu erhalten.

Der Aufwand der Pflege statischer Webseiten kann hoch sein, zum Beispiel wenn eine Site-weite Layoutänderung durchgeführt werden soll. Bei dynamischen Sites muss gegebenenfalls nur eine HTML-Schablone oder eine allgemeine Layout-Vorschrift geändert werden, und alle hiernach erzeugten Seiten spiegeln diese Änderung sofort wider.

Zeitnahe Erstellung der dargestellten Informationen

Da die Seiten dynamischer Websites in kurzen Abständen oder gar just-in-time erzeugt werden, stellen Sie immer den aktuellsten Stand der Rohinformationen dar. Ändert sich zum Beispiel ein Lagerbestand im angebundenen Warenwirtschaftssystem, so wird dem nächsten Online-Besucher automatisch der aktualisierte Bestand angezeigt.

Interaktivität

Die just-in-time Erzeugung der Seiten ermöglicht es, sie benutzerspezifisch zu gestalten. Hat sich zum Beispiel der Benutzer durch einen Login-Mechanismus identifiziert, werden ihm wichtige Informationen hervorgehoben, das Seitenlayout entspricht seinen optischen Vorlieben, usw.

Grundlagen dynamischer Websites

Datenbank

Wie schon erwähnt werden die rohen Daten getrennt von den Layout-Informationen gespeichert. Da es sich meist um strukturierte Daten handelt, eignen sich als Datenablage am besten Datenbanksysteme.

Im Bereich der Open-Source-Software haben sich hier besonders die Datenbanksysteme PostgreSQL und MySQL einen Namen gemacht. Letzteres ist ein relationales Datenbanksystem, das Erstere fügt dem relationalen Modell sogar noch objektorientierte Features hinzu.

Der größte Aufwand beim Entwickeln einer dynamischen Websites entfällt oft auf die Erstellung eines geeigneten Datenmodells und der darauf basierenden Datenbank mit Tabellen, Views, Indizes usw.

Serverside Skripting

Um letztlich HTML-Daten erzeugen zu können, die dann dem Benutzer respektive seinem Browser übermittelt werden, braucht es einer Software, die serverseitig die Datenquellen anzapft und die benötigten Informationen ins HTML-Format bringt, bevor diese an den Client übertragen werden.

Weite Verbreitung hat hier die Skriptsprache Perl gefunden. Perl lehnt sich an die Syntax gängiger Programmiersprachen wie C und C++ an, erbt aber auch wichtige Features der Textdatei-Verarbeitungs-Programme sed und awk. Letztere ermöglichten Perl den Einstieg ins Web, sind doch viele Informationen in Textdateien hinterlegt und HTML letztlich auch nur Text. Perl verfügt mit dem CPAN (Comprehensive Perl Archive Network) über eine riesige Bibliothek fertiger Perl-Module und -Anwendungen für jeden Zweck. Dank Modulen wie DBI.pm zur Datenbank-Anbindung und CGI.pm zur Integration mit Webservern hat Perl einen festen Platz im Repertoire vieler Web-Programmierer.

Steigender Beliebtheit erfreut sich die Skriptsprache PHP ("Professional Home Pages"), die inzwischen in der Version 3, kurz PHP3, verfügbar ist. Für diesen Vortrag habe ich mich für PHP3 als grundlegende Skriptsprache entschieden.

Entwicklung dynamischer Seiten mit PHP3

Der URL der PHP3-Homepage ist http://www.php3.net, ein deutscher Mirror ist http://www.php3.de. Hier finden sich alle Informationen zu PHP3. Die vorbildliche Benutzeroberfläche ist natürlich als dynamische Webseiten mit PHP3 realisiert.

Die Skriptsprache PHP3

PHP lehnt sich in der Syntax an gängige Programmiersprachen an. So wurden zum Beispiel viele Sprachelemente aus C und C++ übernommen.

Ein großer Vorteil von PHP ist, dass PHP-Skripte direkt in eine HTML-Datei eingefügt werden können. Ist der Webserver entsprechend konfiguriert, wird bei Abruf einer PHP-Seite erst der PHP-Parser gestartet, der die Skriptbefehle ausführt und die Ausgabedaten an Stelle des Skripts einfügt. Das resultierende Gemisch auf statischem HTML und von PHP erzeugtem HTML wird dann an den Client übermittelt.

Grundlagen der PHP-Programmierung

Variablen

Variablen werden durch ein vorangestelltes Dollarzeichen deklariert. PHP unterstützt die folgenden Variablen-Typen:

Einer Variable wird in der Regel kein bestimmter Typ fest zugewiesen. Welchen Typs eine Variable ist, entscheidet PHP3 zur Laufzeit. Bei Bedarf kann aber der Typ einer Variable mit der settype() Funktion festgelegt werden.

Initialisiert werden Variablen einfach, indem man ihnen einen Wert zuweist:

	$skalar = "Hallo Welt!";

Arrays können entweder mit der array-Funktion oder sequentiell, Element für Element, initialisiert werden:

	$array = array("Jochen", "Thomas", "Carolin");

	$array[] = "Jochen";
	$array[] = "Thomas";
	$array[] = "Carolin";

Objekte werden wie folgt instantiiert:

	class foo {
          function do_foo () { 
            echo "Doing foo."; 
          }
        }

        $bar = new foo;
        $bar->do_foo ();

Die Lebensdauer von Variablen beschränkt sich auf den Kontext, in dem sie deklariert wurden. Variablen innerhalb von Funktionen sind also automatisch lokal, wenn sie nicht explizit als global deklariert werden.

Funktionen

Wie im obigen Beispiel bereits dargestellt, werden Funktionen wie folgt definiert:

	function do_foo () { 
          echo "Doing foo."; 
        }

Ausdrücke

Bei Ausdrücken lehnt sich PHP stark an die C-Syntax an:

$b = $a = 5;        
$c = $a++;          
$e = $d = ++$b;     

                    

$f = double($d++);  
$g = double(++$e);  
$h = $g += 10;      

Kontrollstrukturen

PHP3 kennt die üblichen Kontrollstrukturen zur Steuerung des Programmablaufs:

Zugriff auf Datenbanken

Die Stärke von PHP3 liegt im Zugriff auf Datenbanken. Hierzu stellt PHP3 Befehlssätze für alle gängigen Systeme bereit:

Stark vereinfacht wird der Zugriff auf Datenbanken durch die Klassenbibliothek phplib (http://phplib.shonline.de). Diese Bibliothek stellt unter anderem eine Datenbank-Klasse zur Verfügung, die die datenbankspezifischen PHP-Befehle kapselt und somit eine einheitliche Schnittstelle zur Datenbank bereitstellt. Der Wechsel zu einem anderen Datenbanksystem ist damit mit minimalem Aufwand möglich; allein die Klassendefinition ist zu ändern.

Integration von HTML und PHP

Als SGML-Processing-Instruction in der Form <? ... ?> werden PHP-Skripts direkt in die HTML-Datei eingebunden. Der PHP-Parser wird vom Webserver aufgerufen und liefert diesem an Stelle der Skripte deren Ausgabe zurück. So ist es problemlos möglich, Kopf- und Fußelemente rein in HTML, die aufbereitete Information jedoch in PHP zu formulieren:

	<h1>Kunden-Adressen</h1>
	<p>Dies sind die Adressen unserer Kunden:</p>

	<table>

	<?

	  $q = new DB_Kontakte;
	  
          $q->query("SELECT * FROM address WHERE type='customer'");

	  while ($q->next_record()) {
	    print "<tr>";
	    print "<td>" . $q->f("name") . "</td>";
	    print "<td>" . $q->f("strasse") . "</td>";
	    print "<td>" . $q->f("plz") . "</td>";
	    print "<td>" . $q->f("ort") . "</td>";
            print "</tr>";
          }

        ?>
	    
        </table>

Alternativ können PHP3-Skripts auch wie folgt eingeschlossen werden:

	<?php ... ?>
	<script language="php"> ... </script>
	<% ... %>

Ein Praxisbeispiel

Die Auflistung aller heutigen Schlagzeilen im Linux BBS erledigt folgende PHP-Seite:

<?php 

  // $Id: headlines.php3,v 1.2 1999/01/30 09:23:52 jlillich Exp $

  include "prepend.php3";        // phplib
  require("common.php3");        // Standard-Definitionen

  header("Content-Type: text/plain");

  $ART_DISPLAY = 10;
  $ART_SELECT = 15;

  $q = new DB_LinuxBBS;

  $q->query("SELECT articles.*, \
	date_format(art_created, '$DATE_FORMAT') as date, \
	date_format(art_created, 'd.m.y') as day, \
	auth_user.username, auth_user.email, \
	arttop.top_picture \
	FROM articles,auth_user, arttop \
	WHERE art_author=auth_user.uid AND art_topic=arttop.top_id \
	ORDER BY art_created DESC \
	LIMIT $ART_SELECT");

  while ($q->next_record()) {

    $artcnt++;
    if (($artcnt > $ART_DISPLAY) && ($q->f("day") != date("d.m.y"))) {
      // zu viele Schlagzeilen oder nicht mehr von heute
      break;
    }

    printf("%s\n", $q->f("art_headline"));
    printf("http://www.linuxbbs.org/showarticle.php3?artid=%s\n", 
	$q->f("art_id"));
    printf("%s\n", $q->f("date"));
  }
?>

Weitere Anwendungsmöglichkeiten

Die phplib bietet, aufbauend auf der oben erwähnten Datenbank-Klasse, nützliche Mechanismen für Session-Management, Authentifizierung und Daten-Persistenz.

Session-Management

Ein Problem bei der Realisierung von Web-Anwendungen ist die Zustandslosigkeit des HTTP-Protokolls. Meist behilft man sich mit Cookies, um eine Abfolge von Handlungen eines bestimmten Besuchers zu verfolgen. Die phplib bietet eine eigene Session-Klasse, die dies automatisch erledigt. Nach Möglichkeit setzt sie ebenfalls Cookies ein, ansonsten kann eine Session durch Mitführen einer Session-ID in dem URL identifiziert werden.

Die Funktionen page_open und page_close ordnen einer Webseite die entsprechenden Klassen zu:

  page_open(array("sess" => "Test_Session", 
                  "auth" => "Test_Auth", 
	          "perm" => "Test_Perm", 
                  "user" => "Test_User"));

  ...

  page_close();

page_open erzeugt hier die Objekte $sess (aus der Klasse Test_Session), $auth aus der Klasse Test_Auth, $perm aus der Klasse Test_Perm und $user aus der Klasse Test_User.

Authentifizierung

phplib bietet durch die auth-Klasse die Möglichkeit, den Zugriff auf die Seite auf eine bestimmte Benutzergruppe zu beschränken. Ruft ein Benutzer eine solche Seite auf, muss er sich erst durch Eingabe seines Benutzernamens identifizieren und durch ein Passwort authentifizieren.

Eine Beschränkung auf Benutzer mit dem Attribut "autoren" geschieht einfach durch den Aufruf

	$perm->check("autoren");

direkt nach dem page_open-Aufruf.

Teile einer HTML-Seite kann man auf folgende Weise schützen:

	<?php
          if ($perm->have_perm("autoren")):
        ?>

         ... geschützter Teil ...

        <?php
          endif
        ?>

Persistenz

Um Daten für die Dauer einer Session oder für einen bestimmten Benutzer dauerhaft (persistent) zu speichern, bietet phplib die Funktionen sess->register und user->register.

Ein Beispiel: Will man den Inhalt der Variablen s für die Dauer der Session erhalten, muss man sie beim Session-Objekt registrieren:

	page_open(...);
	$sess->register("s");

Analog erfolgt die Registrierung einer persistenten User-Variablen bei $user. Beim Ausführen der page_close Funktion werden alle registrierten Variablen für die Session bzw. den User in der Datenbank abgelegt.

Ausblick

Beispiele für mit PHP3 erstellte Websites

PHP hat weite Verbreitung unter Webdesignern gefunden. Unter anderem wird PHP auf folgenden Sites eingesetzt:

Das Linux BBS, die von mir entwickelte Site für Linux-Informationen im deutschsprachigen Raum, findet sich unter http://www.linuxbbs.org und verwendet ebenfalls PHP.

Zend, die optimierte PHP-Engine

Bei Sites mit extrem hohem Seitendurchsatz kann es zu Performance-Engpässen beim Einsatz von PHP3 kommen. Aus diesem Grund wurde das Projekt "Zend" gestartet. Zend ist eine neue PHP-Engine, die das Herzstück von PHP4 darstellen wird, aber auch in eigene Software integriert werden kann.

Durch Vorcompilierung der Zend-Skripts soll die Leistung von Zend die von PHP3 um Größenordnungen übersteigen. Einen festen Termin für die Verfügbarkeit gibt es aber noch nicht. Weitere Informationen sind der Website http://www.zend.com zu entnehmen.