This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Professionelle Softwareentwicklung mit PHP 5 Weiter
Professionelle Softwareentwicklung mit PHP 5 Objektorientierung. Entwurfsmuster. Modellierung. Fortgeschrittene Datenbankprogrammierung. Sebastian Bergmann Text und Abbildungen dieser HTML-Dateien sind der Inhalt des Buchs "Professionelle Softwareentwicklung mit PHP 5" (dpunkt. verlag, ISBN 3-89864-229-1) und urheberrechtlich geschützt. 1. Auflage 2005. Aktualisiert am 07.06.2005.
Widmung Dieses Buch ist meinen Eltern, Engelbert und Beatrice Bergmann, in Liebe gewidmet. Inhaltsverzeichnis Geleitwort Einleitung I. Objektorientierte Programmierung. 1. Grundlagen Einleitung Motivation Klassen und Objekte Polymorphie Referenzen Klassenmethoden, Klassenvariablen und Klassenkonstanten Konstruktoren und Destruktoren Vererbung Abstrakte Klassen und Schnittstellen Fehlerbehandlung mit Ausnahmen Serialisierung von Objekten http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/ (1 von 3)07.06.2005 21:36:58
Professionelle Softwareentwicklung mit PHP 5
Die Reflection API Migration von PHP 4 zu PHP 5 2. Interzeptormethoden Einleitung __autoload __get __set __call __toString 3. Iteratoren Einleitung Die Iterator-Schnittstellen von PHP 5 Die Standard PHP Library (SPL) Die Schnittstelle ArrayAccess 4. Testgetriebene Entwicklung mit PHPUnit Einleitung Testfälle und Zusicherungen Testfälle ausführen und zusammenfassen Automatische Generierung von Testfallklassen Code-Coverage-Analyse von PHP-Applikationen TestDox II. Entwurfsmuster in PHP anwenden. 5. Erzeugungsmuster Einleitung Abstrakte Fabrik Singleton 6. Strukturmuster Einleitung Dekorierer Stellvertreter 7. Verhaltensmuster Einleitung Beobachter Schablonenmethode Strategie Iterator III. PHP-5-Programmierung. 8. XML-Verarbeitung mit PHP Einleitung SimpleXML Simple API for XML (SAX) Document Object Model (DOM) XSL Transformations (XSLT) Objekte mit dem XML_Transformer ins Web bringen
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/ (2 von 3)07.06.2005 21:36:58
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/ (3 von 3)07.06.2005 21:36:58
Kapitel 9. Webdienste mit SOAP
Kapitel 9. Webdienste mit SOAP Teil III. PHP-5-Programmierung.
Zurück
Weiter
Kapitel 9. Webdienste mit SOAP "Wenn eine Idee nicht zuerst absurd erscheint, taugt sie nichts." --Albert Einstein
Einleitung Ein Webdienst ist eine Softwarekomponente, die unter Verwendung von bestehenden Technologien wie HTTP (für den Transport der Daten) und XML (für die Formatierung der Daten) "über das Web" genutzt werden kann. In diesem Kapitel wollen wir die Programmierung von und mit Webdiensten in PHP auf Grundlage der XML-Standards Simple Object Access Protocol (SOAP) und Web Service Description Language (WSDL) betrachten. SOAP dient der Formatierung der Daten, WSDL der Beschreibung der durch den Webdienst angebotenen Funktion (en). Dank der verbesserten Unterstützung für XML-Technologien (siehe Kapitel 8) bietet PHP 5 eine ebenso effiziente wie komfortable Schnittstelle für die Arbeit mit Webdiensten an. Diese ist jedoch in der Standardkonfiguration nicht aktiviert und muss über --enable-soap bei der Konfiguration des Build-Prozesses aktiviert werden (siehe Anhang A). Zurück Objekte mit dem XML_Transformer ins Web bringen
Einen Webdienst programmieren Kapitel 9. Webdienste mit SOAP
Weiter
Einen Webdienst programmieren Jede Funktion oder öffentliche Methode einer Klasse kann in PHP 5 über die Klasse SOAPServer als Webdienst verfügbar gemacht werden. Der Konstruktor der Klasse SOAPServer erwartet entweder den Pfad zu einer WSDL-Beschreibung des Webdienstes als ersten Parameter oder ein assoziatives Array, das Informationen wie die URL des Webdienstes enthält, als zweiten Parameter. Wir betrachten zunächst den Fall, dass keine WSDLBeschreibung vorliegt. In Beispiel 9.1 übergeben wir den Wert NULL als ersten Parameter sowie ein Array mit der Konfiguration des Webdienstes als zweiten Parameter. Mit der Methode setClass() des SOAPServer-Objektes legen wir die Klasse fest, deren öffentliche Methoden wir über den Webdienst verfügbar machen möchten. Mit der Methode handle() "starten" wir den Webdienst. Das bedeutet, dass eine HTTP-Anfrage an das Skript des SOAPServer-Objektes als Anfrage an den Webdienst aufgefasst und entsprechend verarbeitet wird. Beispiel 9.1: Der Hallo-Welt-Webdienst Fehler, die während der SOAP-Verarbeitung auftreten, werden durch eine SOAPFault-Ausnahme repräsentiert und können entsprechend behandelt werden. Nehmen wir einmal an, dass Beispiel 9.1 unter der URL http://localhost.org/HalloWelt.php erreichbar ist. Eine "normale" HTTP-Anfrage für dieses Dokument führt zu einer SOAP-Fehlermeldung, wie sie Abbildung 9.1 zeigt, da sie keine gültige Anfrage im SOAP-Format enthält. Abbildung 9.1. Ausgabe: SOAP-Antwort auf eine HTTP-Anfrage SOAP-ENV:Server Bad Request. Can't find HTTP_RAW_POST_DATA Über eine HTTP-Post-Anfrage (Beispiel 9.2), die im SOAP-XML-Format gestellt wird, können wir die http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.soap.soap-server.html (2 von 5)07.06.2005 21:38:57
Einen Webdienst programmieren
Methode halloWelt() der Klasse Webdienst (Beispiel 9.1) aufrufen. Beispiel 9.2: Eine SOAP-Anfrage an den Hallo-Welt-Webdienst
Hallo Welt Eine solche Anfrage von Hand zu erstellen ist bereits in dem hier gezeigten einfachen Beispiel (keine Parameter, einfacher String als Ergebnis) mühsam. Im folgenden Abschnitt werden wir sehen, wie uns die Klasse SOAPClient diese Arbeit abnimmt. Doch zunächst beschreiben wir den Webdienst mit WSDL in der Datei HalloWelt.wsdl (Beispiel 9.3). Die WSDL-Beschreibung enthält unter anderem Informationen über die Adresse des Webdienstes sowie die Datentypen von Parametern und Rückgabewerten der angebotenen Methoden. Beispiel 9.3: Den Hallo-Welt-Webdienst mit einem WSDL-Dokument beschreiben http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.soap.soap-server.html (3 von 5)07.06.2005 21:38:57
Einen Webdienst programmieren
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.soap.soap-server.html (4 von 5)07.06.2005 21:38:57
Einen Webdienst programmieren
Bei der Erzeugung des SOAPServer-Objektes können wir nun anstelle von NULL und dem assoziativen Parameter-Array den Pfad zur WSDL-Beschreibung aus Beispiel 9.3 angeben (Beispiel 9.4). Für eine HTTP-Anfrage an http://localhost/HalloWelt.php?wsdl liefert das Skript nun die WSDLBeschreibung aus. Beispiel 9.4: Der Hallo-Welt-Webdienst mit WSDL-Beschreibung Zurück Kapitel 9. Webdienste mit SOAP
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.soap.soap-server.html (5 von 5)07.06.2005 21:38:57
Weiter Einen Webdienst verwenden
Einen Webdienst verwenden
Zurück
Einen Webdienst verwenden Kapitel 9. Webdienste mit SOAP
Weiter
Einen Webdienst verwenden Für die Nutzung eines Webdienstes bietet PHP die Klasse SOAPClient an. Ein Objekt dieser Klasse dient hierbei als Stellvertreter (siehe „Stellvertreter“) für den Webdienst: Methodenaufrufe werden automatisch in eine SOAP-Nachricht übersetzt und an den entsprechenden Webdienst weitergeleitet. Die SOAP-Antwort wird verarbeitet und als Ergebnis des Methodenaufrufes zurückgegeben. Intern benutzt die Klasse SOAPClient hierfür eine __call()-Methode (siehe Kapitel 2). Liegt für den zu verwendenden Webdienst eine WSDL-Beschreibung vor, so ist dem Konstruktor der Klasse SOAPClient lediglich Pfad oder URL zu übergeben, wo das WSDL-Dokument zu finden ist. Beispiel 9.5 zeigt den Zugriff auf den Hallo-Welt-Webdienst über dessen WSDL-Beschreibung. Beispiel 9.5: Über die WSDL-Beschreibung auf den Hallo-Welt-Webdienst zugreifen Hallo Welt Die Erzeugung eines SOAPClient-Objektes für die Verwendung eines Webdienstes, für den keine WSDLhttp://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.soap.soap-client.html (1 von 4)07.06.2005 21:38:58
Einen Webdienst verwenden
Beschreibung vorliegt, gestaltet sich etwas aufwändiger. Die sonst aus der WSDL-Beschreibung gewonnenen Informationen müssen dann dem Konstruktor in einem assoziativen Array übergeben werden. Beispiel 9.6: Ohne WSDL-Beschreibung auf den Hallo-Welt-Webdienst zugreifen Hallo Welt Über die Methode __getFunctions() der Klasse SOAPClient können Informationen über die Funktionen des Webdienstes abgefragt werden. Hierzu gehören Name der Funktion, Name und Typ der Parameter sowie der Typ des Rückgabewertes. Beispiel 9.7 zeigt die Ausgabe von __getFunctions() für ein SOAPClient-Objekt, das den Google-Webdienst repräsentiert. Die Methode __getFunctions() gewinnt ihre Informationen aus der WSDL-Beschreibung des Webdienstes. Beispiel 9.7: Die Methode SOAPClient::__getFunctions() http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.soap.soap-client.html (2 von 4)07.06.2005 21:38:58
Einen Webdienst verwenden
Array ( [0] => base64Binary doGetCachedPage(string $key, string $url) [1] => string doSpellingSuggestion(string $key, string $phrase) [2] => GoogleSearchResult doGoogleSearch(string $key, string $q, int $start, int $maxResults, boolean $filter, string $restrict, boolean $safeSearch, string $lr, string $ie, string $oe) ) Beispiel 9.8 demonstriert den Zugriff auf den Google-Webdienst über ein Objekt der Klasse SOAPClient. Damit das Beispiel korrekt funktioniert, muss der erste Parameter der Methode doGoogleSearch() durch einen gültigen Lizenzschlüssel für den Google-Webdienst ersetzt werden. Beispiel 9.8: Auf den Webdienst von Google zugreifen http://www.professionelle-softwareentwicklung-mit-php5.de/ Zurück Einen Webdienst programmieren
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.soap.soap-client.html (4 von 4)07.06.2005 21:38:58
Weiter Kapitel 10. Die MySQLi-Erweiterung
Kapitel 10. Die MySQLi-Erweiterung
Zurück
Kapitel 10. Die MySQLi-Erweiterung Teil III. PHP-5-Programmierung.
Weiter
Kapitel 10. Die MySQLi-Erweiterung "A computer cannot turn bad data into good data." --John R. Pierce
Einleitung Das populäre Open-Source-Datenbanksystem MySQL bietet in seiner derzeit für den produktiven Einsatz empfohlenen Version 4.1 sowie in der kommenden Version 5.0 eine Vielzahl neuer Leistungsmerkmale. Für deren Nutzung bietet PHP 5 die neue MySQLi-Erweiterung ("MySQL Improved"). Diese ist nicht abwärtskompatibel zu PHP 4. Die alte Programmierschnittstelle ("mysql") kann jedoch parallel zu der neuen eingesetzt werden. Anhang A zeigt die entsprechende Build-Konfiguration, um sowohl die alte als auch die neue MySQL-Programmierschnittstelle in PHP 5 nutzen zu können. Zurück Einen Webdienst verwenden
Nach oben Zum Anfang
Weiter Die MySQLi-Erweiterung objektorientiert verwenden
Die MySQLi-Erweiterung objektorientiert verwenden Kapitel 10. Die MySQLi-Erweiterung
Weiter
Die MySQLi-Erweiterung objektorientiert verwenden Die MySQLi-Erweiterung kann prozedural und objektorientiert verwendet werden. Beide Alternativen bieten jedoch denselben Funktionsumfang. Wir wollen zunächst die objektorientierte Verwendung betrachten. Beispiel 10.1 zeigt die objektorientierte Verwendung der MySQLi-Erweiterung analog zu dem in Beispiel 1.1 gezeigten Beispiel, das die MySQL-Erweiterung verwendet. Beispiel 10.1: Die MySQLi-Erweiterung objektorientiert verwenden Eine Eigenheit der MySQLi-Erweiterung stellt die Verwendung von Unterstrichen in den Namen der Methoden und Instanzvariablen anstelle der üblichen StudlyCaps-Notation
[10]
dar. Tabelle 10.1. Die Klassen der MySQLi-Erweiterung Klasse
Aufgabe
MySQLi
Repräsentiert die Verbindung zum MySQL-Server.
MySQLi_Stmt
Repräsentiert eine vorbereitete Anfrage.
MySQLi_Result Repräsentiert das Ergebnis einer Anfrage. Werden für die Verbindung zum MySQL-Server nur die Verbindungsparameter (Hostname oder Socket) sowie die Kennungsdaten (Benutzername und Passwort) benötigt, so können diese direkt dem Konstruktor der Klasse MySQLi übergeben werden.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.mysqli.oop.html (1 von 3)07.06.2005 21:39:00
Die MySQLi-Erweiterung objektorientiert verwenden
Sollen für die Verbindung stattdessen erweiterte Parameter, beispielsweise für eine Verschlüsselung der Client-Server-Kommunikation, gesetzt werden, so ist mit der Funktion mysqli_init() zunächst ein MySQLi-Objekt zu erzeugen. Über die entsprechenden Methoden, beispielsweise ssl_set(), können dann die entsprechenden Einstellungen vorgenommen werden, bevor die eigentliche Verbindung mit der Methode real_connect() hergestellt wird. Diese Methode akzeptiert dieselben Parameter wie der Konstruktor. Die Methode query() der Klasse MySQLi liefert ein Objekt der Klasse MySQLi_Result. Dieses kapselt die Ergebniszeilen der Anfrage. Da die Klasse MySQLi_Result leider nicht die Schnittstelle Iterator anbietet, kann das Objekt nicht direkt mit dem foreachOperator verwendet werden. Stattdessen ist eine entsprechende while-Schleife zu verwenden (siehe Beispiel 10.1). Die Klassen und Methoden der MySQLi-Erweiterung benutzen in PHP 5.0
[11]
leider von
Haus aus keine Ausnahmen, um die Behandlung von Fehlersituationen zu ermöglichen. Daher müssen entweder Funktionen wie mysqli_connect_errno() und mysqli_connect_error() (siehe Beispiel 10.1) verwendet werden, oder die Klasse MySQLi muss entsprechend durch Vererbung angepasst werden. Beispiel 10.2 zeigt eine von MySQLi abgeleitete Klasse, die bei Fehlern während des Verbindungsaufbau sowie bei Anfragefehlern eine entsprechende Ausnahme auslöst. Beispiel 10.2: Die MySQLi-Erweiterung um Ausnahmenbehandlung erweitern
[10]
Bei der Notation von Bezeichnernamen gibt es zwei etablierte Möglichkeiten, um
Wörter, die Bestandteil des Namens sind, zu trennen. In der prozeduralen Programmierung geschieht dies meist mit einem Unterstrich, in der objektorientierten Programmierung benutzt man Groß- und Kleinbuchstaben, um die Wörter voneinander abzugrenzen. Hierbei wird das erste Zeichen eines Namens klein geschrieben, jedes neue Wort beginnt mit einem Großbuchstaben. [11]
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.mysqli.oop.html (3 von 3)07.06.2005 21:39:00
Vorbereitete Anfragen verwenden
Zurück
Vorbereitete Anfragen verwenden Kapitel 10. Die MySQLi-Erweiterung
Weiter
Vorbereitete Anfragen verwenden Das neue Client-Server-Protokoll, das MySQL seit Version 4.1 verwendet, unterstützt die Verwendung von vorbereiteten Anfragen. Diese ermöglichen eine effizientere Verarbeitung von Anfragen, die dynamisch zusammengesetzt werden. Hierzu werden die variablen Teile der Anfrage -- beispielsweise Werte, nach denen in einer Spalte einer Tabelle gesucht werden soll -- durch einen Platzhalter ersetzt. An diese Platzhalter können im Anschluss die entsprechenden Werte gebunden werden. Eine vorbereitete Anfrage muss für die mehrmalige Ausführung mit unterschiedlichen Werten nur einmal an den Datenbankserver übermittelt (und dort für die Ausführung vorbereitet) werden. Bei nachfolgenden Anfragen mit geänderten Werten müssen nur noch die neuen Werte übermittelt werden. Dies spart sowohl Zeit bei der Kommunikation zwischen Client und Server als auch bei der Ausführung der Anfrage. In Beispiel 10.3 erzeugen wir mit $mysqli->prepare() zunächst ein Objekt der Klasse MySQLi_Stmt. Dieses repräsentiert die Anfrage INSERT INTO tabelle (spalte) VALUES(?). Im Anschluss binden wir mit der Methode bind_param() die PHP-Variable $string an den Platzhalter der Anfrage. Ein Aufrufen der Methode execute() führt die vorbereitete Anfrage mit dem jeweils aktuellen Wert der PHPVariablen $string als Wert für ? auf. Beispiel 10.3: PHP-Variablen an die Platzhalter einer Anfrage binden Der erste Parameter der Methode bind_param() enthält einen String, in dem jedes Zeichen für den Typ einer gebundenen Variablen steht. Nach diesem ersten Parameter folgen die PHP-Variablen, die an die Anfrage gebunden werden sollen, in der entsprechenden Reihenfolge. Tabelle 10.2 zeigt die möglichen Typen und ihre Zeichen. Tabelle 10.2. Die verfügbaren Typen für gebundene Parameter
http://www.professionelle-softwareentwicklung-mit-php5....auflage/programming-php.mysqli.prepared-statements.html (1 von 2)07.06.2005 21:39:01
Vorbereitete Anfragen verwenden
Typ Beschreibung i
Variable ist eine Integerzahl.
d
Variable ist eine Gleitpunktzahl.
s
Variable ist ein String.
b
Variable ist ein BLOB. Dieser wird in mehreren Paketen an den Datenbankserver gesendet.
Mit der Methode bind_result() der Klasse MySQLi_Stmt können die Spalten der Ergebniszeilen einer vorbereiteten Anfrage an PHP-Variablen gebunden werden (siehe Beispiel 10.4). Hierbei entfällt die (bei Ergebniszeilen mit vielen Spalten teure) Erzeugung eines Arrays für jede Ergebniszeile. Beispiel 10.4: Die Spalten der Ergebniszeilen an PHP-Variablen binden foo bar Innerhalb der while-Schleife in Beispiel 10.4 enthält die PHP-Variable $spalte stets den Inhalt der Spalte spalte der aktuellen Ergebniszeile der Anfrage. Zurück Die MySQLi-Erweiterung objektorientiert verwenden
Nach oben Zum Anfang
Weiter Die MySQLi-Erweiterung prozedural verwenden
http://www.professionelle-softwareentwicklung-mit-php5....auflage/programming-php.mysqli.prepared-statements.html (2 von 2)07.06.2005 21:39:01
Die MySQLi-Erweiterung prozedural verwenden
Die MySQLi-Erweiterung prozedural verwenden Zurück Weiter Kapitel 10. Die MySQLi-Erweiterung
Die MySQLi-Erweiterung prozedural verwenden Bei der prozeduralen Verwendung der MySQLi-Erweiterung ist zu betrachten, dass sich die Funktionsnamen gegenüber der MySQLErweiterung von mysql_*() zu mysqli_*() geändert haben. Ferner erwarten die Funktionen der MySQLi-Erweiterung die explizite Angabe der zu verwendenden Verbindungsressource als Parameter für Funktionen wie beispielsweise mysqli_query(). Die Angabe dieses Parameters war bei der MySQL-Erweiterung optional, da diese die Verwendung einer Standardverbindung unterstützte. Eine Standardverbindung wird von der MySQLi-Erweiterung ebensowenig unterstützt wie persistente Verbindungen. Letztere werden in Zukunft durch die Verwendung eines Verbindungsmanagers ersetzt, sobald dieser als Bestandteil von MySQL 5.0 verfügbar ist. Beispiel 10.5 zeigt die prozedurale Verwendung der MySQLiErweiterung analog zu dem in Beispiel 10.1 gezeigten Beispiel. Beispiel 10.5: Die MySQLi-Erweiterung prozedural verwenden Zurück Vorbereitete Anfragen verwenden
Nach oben Zum Anfang
Weiter Teil IV. Fortgeschrittene Datenbankprogrammierung.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.mysqli.procedural.html (2 von 2)07.06.2005 21:39:02
Teil IV. Fortgeschrittene Datenbankprogrammierung.
Teil IV. Fortgeschrittene Datenbankprogrammierung. Zurück Weiter Kapitel 11 Stellt die Datenbankabstraktionslösung Creole vor, die die Grundlage für Propel bildet. Kapitel 12 Stellt mit Propel eine Lösung für das objektrelationale Mapping in PHP vor. Zurück Die MySQLi-Erweiterung prozedural verwenden
Kapitel 11. Creole Teil IV. Fortgeschrittene Datenbankprogrammierung.
Weiter
Kapitel 11. Creole "If you torture the data enough, it will confess." --Ronald Coase
Einleitung Soll eine Anwendung mit unterschiedlichen Datenbankmanagementsystemen arbeiten können, so wird eine Abstraktion von der Datenbank benötigt. Diese bietet eine einheitliche Programmierschnittstelle für die Arbeit mit den spezifischen Programmierschnittstellen der unterschiedlichen Systeme (beispielsweise den MySQL- und PostgreSQL-Erweiterungen von PHP). Über diese Abstraktion der Programmierschnittstellen hinaus können Unterschiede in der Implementierung des SQL-Standards durch die Datenbankmanagementsysteme berücksichtigt und vor dem Programmierer verborgen werden. Creole ist eine an Java Database Connectivity (JDBC) angelehnte DatenbankabstraktionsLösung und ermöglicht die vollständig objektorientierte, von dem verwendeten Datenbanksystem unabhängige Programmierung von Datenbankanwendungen mit PHP. Abbildung 11.1 zeigt die Installation von Creole und Jargon, einem Paket mit nützlichen Helferklassen. Abbildung 11.1. Installation von Creole und Jargon pear install http://creole.phpdb.org/pear/creole-current.tgz pear install http://creole.phpdb.org/pear/jargon-current.tgz Zurück Teil IV. Fortgeschrittene Datenbankprogrammierung.
Verbindung zur Datenbank Für das Verbinden zur Datenbank stellt Creole die statische Methode Creole::getConnection() zur Verfügung. Sie erwartet die Verbindungsdaten in PEAR-DSN-Notation (DSN: "Data Source Name") als Array oder String. Die Bestandteile der PEAR-DSNNotation sind: ●
phptype ist die PHP-Erweiterung (mysql, mysqli, odbc, ...), die für die Verbindung zum Datenbankserver verwendet werden soll. Aufgrund dieses Wertes wählt Creole den Datenbanktreiber aus.
●
protocol ist das Kommunikationsprotokoll (TCP/IP, UNIX, ...), über das die Verbindung zum Datenbankserver aufgebaut werden soll.
●
hostspec ist die Host-Spezifikation des Datenbankservers.
●
database ist die im Datenbankserver zu verwendende Datenbank.
●
username ist der Benutzername für die Anmeldung am Datenbankserver.
●
password ist das Kennwort für die Anmeldung am Datenbankserver.
Abbildung 11.2. Die Creole-Schnittstelle Connection
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.creole.connection.html (1 von 3)07.06.2005 21:39:04
Verbindung zur Datenbank
Beispiel 11.1: Aufruf der Methode Creole::getConnection() Die in Beispiel 11.1 gezeigte Verbindung würde in String-Notation als mysql://root@localhost/test geschrieben.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.creole.connection.html (2 von 3)07.06.2005 21:39:04
Verbindung zur Datenbank
Als zweiten, optionalen Parameter akzeptiert die Methode Creole::getConnection() einen Bitwert, der sich aus den Werten Creole::PERSISTENT und Creole::NO_ASSOC_LOWER zusammensetzen kann. Ersterer aktiviert die Verwendung einer persistenten Verbindung, falls der verwendete Datenbanktreiber beziehungsweise die Datenbank dies unterstützt. Der zweite Wert deaktiviert die automatische Umwandlung von Feldnamen in Kleinbuchstaben, die Creole standardmäßig zu Kompatibilitätszwecken durchführt. Zurück Kapitel 11. Creole
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.creole.connection.html (3 von 3)07.06.2005 21:39:04
Ausführen von SQL-Anfragen
Zurück
Ausführen von SQL-Anfragen Kapitel 11. Creole
Weiter
Ausführen von SQL-Anfragen Der einfachste Weg, eine lesende Datenbankabfrage mit Creole auszuführen, ist die Verwendung der Methode executeQuery($sql) des Connection-Objektes. Diese erwartet die SQL-Anfrage als Parameter und liefert ein ResultSet-Objekt zurück, das die Ergebniszeilen der Abfrage kapselt. Abbildung 11.3. Die Schnittstelle ResultSet und die Klasse ResultSetIterator
Für das Durchlaufen (englisch: Scrolling) der Ergebniszeilen bietet das ResultSet-Objekt die folgenden Methoden an: ●
first() setzt den Cursor auf die erste Ergebniszeile.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.creole.query.html (1 von 4)07.06.2005 21:39:14
Ausführen von SQL-Anfragen
●
next() geht zur nächsten Ergebniszeile.
●
relative($offset) setzt den Cursor relativ zur aktuellen Ergebniszeile.
●
previous() geht zur vorherigen Ergebniszeile.
●
last() setzt den Cursor auf die letzte Ergebniszeile.
Der Zugriff auf die Felder einer Ergebniszeile kann zum einen mit Methoden wie getInt($field) oder getString($code) erfolgen. Zum anderen kann die allgemeine Methode get($field) verwendet werden. Dies ist sinnvoll, falls die automatische Konvertierung des Felddatentyps der Datenbank in einen PHP-Datentyp, wie sie die spezialisierten Methoden bieten, nicht gewünscht ist. Beispiel 11.2: Lesender Zugriff mit der Methode Connection::executeQuery($sql) Da das ResultSet-Objekt die Schnittstelle IteratorAggregate (siehe Kapitel 3) anbietet, kann alternativ der foreach-Operator benutzt werden, um die Ergebniszeilen (unter Verwendung eines ResultSetIterator-Objektes) zu verarbeiten. Beispiel 11.3: Alternative Verwendung des ResultSet-Objektes mit dem foreach-Operator Analog zu der Methode executeQuery($sql) bietet das Connection-Objekt die Methode executeUpdate($sql) für den schreibenden Zugriff auf die Datenbank an. Die Methode liefert als Rückgabewert die Anzahl der geänderten Zeilen. In Beispiel 11.4 löschen wir alle Zeilen einer Tabelle mit der Methode executeUpdate($sql). Beispiel 11.4: Schreibender Zugriff mit der Methode Connection::executeUpdate($sql) Der nächstkomplexere Weg, eine lesende Datenbankabfrage mit Creole auszuführen, besteht in der Verwendung eines Statement-Objektes. In Beispiel 11.5 benutzen wir zunächst die Methode createStatement() des Connection-Objektes, um ein Statement-Objekt zu erzeugen. Auf diesem können wir dann wie gehabt die Methode executeQuery(sql) aufrufen, um ein ResultSet-Objekt mit den Ergebniszeilen zu erhalten. Abbildung 11.4. Die Creole-Schnittstelle Statement
Der Mehraufwand, den das Erzeugen eines Statement-Objektes mit sich bringt, lohnt sich erst dann, wenn die Ergebniszeilen limitiert werden sollen. Beispielsweise lässt sich die MySQL-spezifische Anfrage SELECT foo FROM bar LIMIT 5,10, die maximal 10 Ergebniszeilen (beginnend mit der 6.) liefert, datenbankunabhängig formulieren (wie in Beispiel 11.5 gezeigt). Beispiel 11.5: Lesender Zugriff mit einem Statement-Objekt Für Datenbankabfragen, die dynamisch vor ihrer Ausführung zusammengesetzt werden, sieht Creole die Verwendung von vorbereiteten Anfragen (siehe Kapitel 10) mit einem Objekt der Klasse PreparedStatement vor. Hierbei werden Fragezeichen als Platzhalter im SQL-Code verwendet. Mit Hilfe von Methoden wie setInt($paramIndex, $value) werden diese Platzhalter mit Werten gefüllt. Abbildung 11.5. Die Creole-Schnittstelle PreparedStatement
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.creole.query.html (3 von 4)07.06.2005 21:39:14
Ausführen von SQL-Anfragen
In Beispiel 11.6 verwenden wir ein PreparedStatement-Objekt, um mit einer dynamisch erzeugten Anfrage nur ausgewählte Zeilen (WHERE foo = ?) aus der Tabelle zu löschen. Beispiel 11.6: Schreibender Zugriff mit einem PreparedStatement-Objekt Bietet die verwendete Datenbank native Unterstützung für vorbereitete Anfragen (wie beispielsweise MySQL, siehe Kapitel 10), so wird diese benutzt, um die Verarbeitung der SQL-Anfragen effizienter durchführen zu können. Zurück Verbindung zur Datenbank
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.creole.query.html (4 von 4)07.06.2005 21:39:14
Weiter Metadaten
Metadaten
Zurück
Metadaten Kapitel 11. Creole
Weiter
Metadaten Creole bietet eine an die Programmierschnittstelle von Hibernate angelehnte Möglichkeit für die Introspektion von Datenbanken an. Die Methode getDatabaseInfo() der Klasse Connection liefert hierzu ein DatabaseInfoObjekt mit den Metadaten der aktuell benutzten Datenbank (Beispiel 11.7). Beispiel 11.7: Metadaten mit Connection::getDatabaseInfo() abfragen Tabelle: bar foo: int bar: text Zurück Ausführen von SQL-Anfragen
Kapitel 12. Propel Teil IV. Fortgeschrittene Datenbankprogrammierung.
Weiter
Kapitel 12. Propel "It is a capital mistake to theorize before one has data. Insensibly one begins to twist facts to suit theories, instead of theories to suit facts." --Sherlock Holmes
Einleitung Propel ist eine an Apache Torque angelehnte Lösung für die Abbildung von PHP-Klassen in einer relationalen Datenbank. Sie ermöglicht zum einen das Speichern von PHP-Objekten in einer Datenbank und umgekehrt die Kapselung von Datenbankinhalten durch PHP-Objekte. Propel dient hierbei als Brücke zwischen der Datenbank und den PHP-Klassen der eigentlichen Anwendung. Der Programmierer der Anwendung muss keine SQL-Anfragen direkt an den Datenbankserver richten, da diese von Propel automatisch erzeugt werden. Somit ist bei dem Wechsel von einem Datenbankmanagementsystem zu einem anderen lediglich eine Konfigurationsdatei anzupassen. Propel besteht aus zwei Komponenten: Mit dem Propel-Generator werden aus einer XML-Spezifikation des Datenmodells die entsprechenden PHP-Klassen sowie eine Datei mit den für die Erzeugung der entsprechenden Datenbank und Tabellen benötigten SQL-Anweisungen erzeugt. Die PropelLaufzeitumgebung bildet die Grundlage für die Verwendung der durch den Propel-Generator generierten PHP-Klassen. Propel benötigt neben Creole (siehe Kapitel 11) auch die Pakete PEAR::Log und Phing (PHing Is Not GNU make). Diese sind vor der Installation von Propel zu installieren. Bei Phing handelt es sich um eine PHPhttp://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.html (1 von 2)07.06.2005 21:39:16
Kapitel 12. Propel
Portierung des in der Java-Welt beliebten Build-Werkzeugs Apache Ant, die für den Propel-Generator benötigt wird. Abbildung 12.1. Installation von PEAR::Log pear install --alldeps Log Abbildung 12.2. Installation von Phing pear install http://phing.info/pear/phing-current.tgz Abbildung 12.3. Installation von Propel pear install http://propel.phpdb.org/pear/propel_runtime-current.tgz pear install http://propel.phpdb.org/pear/propel_generator-current.tgz Zurück Metadaten
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.html (2 von 2)07.06.2005 21:39:16
Weiter Spezifizieren des Datenmodells in XML
Spezifizieren des Datenmodells in XML
Zurück
Spezifizieren des Datenmodells in XML Kapitel 12. Propel
Weiter
Spezifizieren des Datenmodells in XML Beispiel 12.1 zeigt die XML-Spezifikation eines Datenmodells für einen Buchkatalog, in dem zu jedem Buch neben Titel und ISBN auch Autor und Verlag gespeichert werden. Autoren und Verlage werden hierbei in separaten Tabellen gespeichert und über Fremdschlüssel mit der Buchtabelle verknüpft. Beispiel 12.1: Spezifikation des Datenmodells in XML
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.xml.html (1 von 7)07.06.2005 21:39:17
Spezifizieren des Datenmodells in XML
Das Wurzelelement (siehe Tabelle 12.1) gruppiert die
-Elemente (siehe Tabelle 12.2), mit denen die einzelnen Tabellen spezifiziert werden. Mit den -Elementen (siehe Tabelle 12.3) werden die Spalten einer Tabelle spezifiziert. Hierbei werden unter anderem der Datentyp sowie Schlüsselinformationen festgelegt. Über ein -Element kann durch einen Fremdschlüssel eine Spalte einer anderen Tabelle referenziert werden. Tabelle 12.1. Attribute des -Elementes Name
Verfügbare Werte
Standardwert Erforderlich
name defaultIdMethod
Ja "native", "none"
"none"
Nein
package
Projektname
Nein
baseClass
BaseObject
Nein
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.xml.html (2 von 7)07.06.2005 21:39:17
"underscore" (oder Wert des Attributes phpNamingMethod des
-Elementes)
Nein
inheritance
"false"
Nein
"single", "false"
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.xml.html (4 von 7)07.06.2005 21:39:17
Spezifizieren des Datenmodells in XML
inputValidator
Nein
Beispiel 12.2 zeigt die Konfiguration des Objektspeichers für den Buchkatalog mit der Konfigurationsdatei runtime-conf.xml. Beispiel 12.2: Konfiguration des Objektspeichers in XML propel-books 7 mysql mysql localhost books root
Mit dem Propel-Generator können nun die für die Erzeugung der entsprechenden Datenbank und Tabellen benötigten SQL-Anweisungen (Beispiel 12.3) sowie die entsprechenden PHP-Klassen (Abbildung 12.5) erzeugt werden.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.xml.html (5 von 7)07.06.2005 21:39:17
Spezifizieren des Datenmodells in XML
Abbildung 12.4. Datenbank-Schema und PHP-Klassen mit dem Propel-Generator erzeugen propel-gen /home/sb/books Beispiel 12.3: Die generierte Datei schema.sql DROP TABLE IF EXISTS author; CREATE TABLE author( author_id INTEGER NOT NULL COMMENT 'Autor-ID', first_name VARCHAR(128) NOT NULL COMMENT 'Autor Vorname', last_name VARCHAR(128) NOT NULL COMMENT 'Autor Nachname', PRIMARY KEY (author_id) ) TYPE=InnoDB COMMENT='Autor-Tabelle'; DROP TABLE IF EXISTS publisher; CREATE TABLE publisher( publisher_id INTEGER NOT NULL COMMENT 'Verlag-ID', name VARCHAR(128) NOT NULL COMMENT 'Verlag-Name', PRIMARY KEY (publisher_id) ) TYPE=InnoDB COMMENT='Verlag-Tabelle'; DROP TABLE IF EXISTS book; CREATE TABLE book( book_id INTEGER title VARCHAR(255) isbn VARCHAR(24) author_id INTEGER publisher_id INTEGER
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.xml.html (7 von 7)07.06.2005 21:39:17
Weiter Objektmodell und Objektspeicher
Objektmodell und Objektspeicher
Zurück
Objektmodell und Objektspeicher Kapitel 12. Propel
Weiter
Objektmodell und Objektspeicher Der Propel-Generator erzeugt für jede Tabelle (beispielsweise author) unter anderem eine abstrakte Basisklasse (BaseAuthor), die sich von der abstrakten Klasse BaseObject der Propel-Laufzeitumgebung ableitet, sowie eine leere, aber konkrete Kindklasse (Author) hiervon. Die abstrakte Klasse BaseAuthor aus unserem Buchkatalog-Beispiel enthält Methoden wie getFirstName() und setFirstName(v), um auf die Daten eines Autors lesend und schreibend zugreifen zu können. In der konkreten Kindklasse Author kann zusätzliche Logik implementiert werden. Diese geht nicht verloren, wenn die PHP-Klassen neu aus der XML-Spezifikation des Datenmodells erstellt werden. Abbildung 12.5 zeigt ein UML-Klassendiagramm für die generierten Klassen Author, Book und Publisher, die wir im Folgenden verwenden wollen, um auf den Buchkatalog zuzugreifen. Abbildung 12.5. Die generierten Klassen Author, Book und Publisher
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.object-model-object-store.html (1 von 5)07.06.2005 21:39:20
Objektmodell und Objektspeicher
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.object-model-object-store.html (2 von 5)07.06.2005 21:39:20
Objektmodell und Objektspeicher
In Beispiel 12.4 initialisieren wir zunächst die Propel-Laufzeitumgebung durch Laden der entsprechenden Klassen sowie der Konfigurationsdatei runtime-conf.php, die aus runtime-conf.xml (Beispiel 12.2) erzeugt wurde. Im Anschluss erzeugen wir je ein Objekt der Klassen Author, Book und Publisher und verwenden die entsprechenden set-Methoden, um Vorname und Nachname des Autors, Name des Verlags, ISBN und Titel des Buches zu setzen. Der erste Aufruf der Methode save() auf dem Book-Objekt führt dazu, dass je eine neue Zeile in die Tabellen author, publisher und book geschrieben wird. Der zweite Aufruf von save() fügt nur jeweils eine neue Zeile in die Tabellen author und book ein, da dasselbe PublisherObjekt zuvor verwendet (und somit derselbe Verlag referenziert) wird. Beispiel 12.4: Ein neues Buch anlegen http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.object-model-object-store.html (3 von 5)07.06.2005 21:39:20
Objektmodell und Objektspeicher
Neben den Klassen Author, Book und Publisher, deren Objekte jeweils einen Eintrag der entsprechenden Tabelle repräsentieren, generiert der Propel-Generator mit den Klassen AuthorPeer, BookPeer und PublisherPeer Helferklassen mit statischen Methoden für den Zugriff auf die Tabellen author, book und publisher. Abbildung 12.6. Die generierten Klassen BaseAuthorPeer und AuthorPeer
In Beispiel 12.5 nutzen wir die Methode retrieveByPK() der Klasse AuthorPeer, um über den Primärschlüssel an eine Zeile der Tabelle author zu gelangen. So können wir mit setFirstName() den Vornamen des entsprechenden Autors ändern und das Objekt im Anschluss über save(), das in diesem Fall eine UPDATE-Anweisung ausführen wird, in der Datenbank speichern. http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.object-model-object-store.html (4 von 5)07.06.2005 21:39:20
Objektmodell und Objektspeicher
Beispiel 12.5: Den Vornamen eines Autors ändern Ein Eintrag einer Tabelle kann durch Aufrufen der Methode delete() auf einem entsprechenden Objekt gelöscht werden (Beispiel 12.6). Beispiel 12.6: Ein Buch löschen Zurück Spezifizieren des Datenmodells in XML
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.object-model-object-store.html (5 von 5)07.06.2005 21:39:20
Weiter Nach Objekten im Objektspeicher suchen
Nach Objekten im Objektspeicher suchen
Zurück
Nach Objekten im Objektspeicher suchen Kapitel 12. Propel
Weiter
Nach Objekten im Objektspeicher suchen Bislang konnten wir auf Objekte in der Datenbank nur über den Primärschlüssel und die Methode retrieveByPK() der entsprechenden Helferklasse zugreifen. Wenn wir nach einem Objekt suchen, so wird es in der Regel jedoch der Fall sein, dass wir den Primärschlüssel nicht kennen. Hier kommen die Klasse Criteria sowie die Methode doSelect() der Helferklassen ins Spiel. Abbildung 12.7. Die Klasse PropelCriteria
Die Klasse Criteria kapselt eine beliebige Anzahl von Kriterien, nach denen mit der Methode doSelect() gesucht werden kann. In Beispiel 12.7 erzeugen wir zunächst ein Criteria-Objekt. Mit dem ersten Aufruf der Methode add() legen wir fest, dass der Vorname des Autors "Sebastian" sein soll. Die Konstante AuthorPeer::FIRST_NAME enthält hierbei den Namen der entsprechenden Tabellenspalte, auf die das Suchkriterium angewendet werden soll. http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.criteria.html (1 von 3)07.06.2005 21:39:21
Nach Objekten im Objektspeicher suchen
Beim zweiten Aufruf von add() nutzen wir den optionalen dritten Parameter der Methode, um den zu verwendenden Vergleichsoperator festzulegen: Criteria::NOT_EQUAL bedeutet in diesem Fall, dass der Nachname nicht "Nohn" sein soll. Die verfügbaren Vergleichsoperatoren sind die Konstanten der Klasse Criteria in Abbildung 12.7. Schließlich wird das Criteria-Objekt an die Methode AuthorPeer::doSelect() übergeben, die ein Array der passenden Author-Objekte als Ergebnis liefert. Beispiel 12.7: Suche nach Objekten mit einfachen Kriterien Sebastian Bergmann Intern führt die Ausführung der Methode add() des Criteria-Objektes dazu, dass ein neues Objekt der Klasse Criterion erzeugt und dem Criteria-Objekt hinzugefügt wird. Alternativ kann man ein solches Criterion-Objekt auch von Hand erzeugen und ebenfalls über die Methode add() einem Criteria-Objekt hinzufügen. Möchte man Suchkriterien miteinander kombinieren, beispielsweise mit einer OderVerknüpfung, so muss man zunächst entsprechende Criterion-Objekte über die Methode getNewCriterion() eines Criteria-Objektes erzeugen. Über die Methode addOr() vollzieht man dann die Oder-Verknüpfung der beiden Suchkriterien und fügt diese dann dem Criteria-Objekt hinzu. So wird in Beispiel 12.8 nach Autoren gesucht, deren Vorname "Sebastian" oder "Hakan" ist. Beispiel 12.8: Suche nach Objekten mit verknüpften Kriterien Sebastian Bergmann Hakan Kücükyilmaz Zurück Objektmodell und Objektspeicher
Nach oben Zum Anfang
Weiter Teil V. Werkzeuge für die Entwicklung von PHP-Projekten.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/db.propel.criteria.html (3 von 3)07.06.2005 21:39:21
Teil V. Werkzeuge für die Entwicklung von PHP-Projekten.
Teil V. Werkzeuge für die Entwicklung von PHP-Projekten. Zurück Weiter Kapitel 13 Stellt mit phpDocumentor und Doxygen Werkzeuge für die automatische Erzeugung von Entwickler-Dokumentation aus PHP-Quelltexten vor. Kapitel 14 Stellt mit ArgoUML und Poseidon for UML zwei Werkzeuge für die Modellierung von PHP-Applikationen mit Hilfe der Unified Modeling Language (UML) und mit UML2PHP ein Werkzeug für die modellgetriebene Entwicklung (MDA) vor. Zurück Nach Objekten im Objektspeicher suchen
Kapitel 13. Code-Dokumentation Teil V. Werkzeuge für die Entwicklung von PHP-Projekten.
Zurück
Weiter
Kapitel 13. Code-Dokumentation "Well-commented is, like beauty, in the eye of the beholder." --http://c2.com/cgi/wiki?WellCommentedCode
Einleitung Neben dem Testen (siehe Kapitel 4) wird auch die Dokumentation von Programmcode häufig vernachlässigt. Dabei ist diese gerade bei der auf Wiederverwendung ausgerichteten objektorientierten Programmierung wichtig: Ohne entsprechende Dokumentation ist es für den Verwender einer Klasse schwierig, diese korrekt einzusetzen. Auf dem weltweit ersten PHP-Kongress im Oktober 2000 in Köln hat Ulf Wendel mit PHPDoc den ersten Ansatz für die PHP-CodeDokumentation vorgestellt. Dieser basierte auf dem JavaWerkzeug JavaDoc. Die von Ulf Wendel eingeführten Tags (siehe Tabelle 13.1) bilden bis heute die Grundlage sämtlicher Werkzeuge für die Dokumentation von PHP-Quelltexten. Zurück
Nach oben
Teil V. Werkzeuge für die Zum Anfang Entwicklung von PHPProjekten.
phpDocumentor phpDocumentor ist die Standardlösung für die Erzeugung von Entwicklerdokumentation aus PHP-Quelltexten heraus. Hierbei werden Formatierungsanweisungen in den Quelltext-Kommentaren verwendet, um beispielsweise Typ und Anzahl der Parameter einer Methode sowie deren Aufgabe und Rückgabewert zu dokumentieren. Diese Informationen werden von phpDocumentor aus dem Quelltext extrahiert und in unterschiedlichen Formaten aufbereitet. Dank des PEAR-Installers gestaltet sich die Installation von phpDocumentor gewohnt einfach (Abbildung 13.1). Abbildung 13.1. Installation von phpDocumentor pear install --alldeps phpDocumentor phpDocumentor unterstützt die Dokumentation von Inklusionsanweisungen, Konstanten, Funktionen und Klassen sowie deren Instanzvariablen und Methoden. phpDocumentor erwartet die Dokumentation eines Codeelementes in einem Kommentar, der direkt vor dem Element in DocBlock-Notation (Beispiel 13.1) zu schreiben ist. Ein DocBlock ist ein erweiterter PHP-Kommentar im C++-Stil. Er wird mit /** eingeleitet. Ferner beginnt jede weitere Zeile mit einem *. Beispiel 13.1: Ein DocBlock Tabelle 13.1 zeigt die wichtigsten Tags, die phpDocumentor unterstützt. Tabelle 13.1. Die wichtigsten Tags von phpDocumentor Tag
Beschreibung
@abstract, @final und @static
Dokumentation von Klassen oder Methoden als abstrakt, final oder statisch.
@access {public|protected|private} Sichtbarkeit des dokumentierten Codeelementes. @param Typ $name Beschreibung
Dokumentation eines Parameters einer Funktion oder Methode.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.code-documentation.phpdocumentor.html (1 von 6)07.06.2005 21:39:24
phpDocumentor
@return Typ Beschreibung
Dokumentation des Rückgabewertes einer Funktion oder Methode.
@author und @copyright
Dokumentation von Autor und Urheberrechtsinformation für das Codeelement.
@see
Fügt einen Verweis auf die Dokumentation eines anderen Codeelementes ein.
@version
Dokumentiert die Version des Codeelementes.
@since
Dokumentiert, seit welcher Version das Codeelement existiert.
@deprecated
Markiert das dokumentierte Codeelement als ausgemustert.
Beispiel 13.2 zeigt den Quelltext einer Klasse ohne Codekommentare. Beispiel 13.2: Eine Klasse ohne Dokumentationskommentare Abbildung 13.2 zeigt den Aufruf von phpDocumentor von der Kommandozeile aus. Der Parameter -t . setzt das Ausgabeverzeichnis auf das aktuelle Verzeichnis, über -f Klasse.php legen wir die Eingabedatei fest. Abbildung 13.2. Aufruf von phpDocumentor phpdoc -t . -f Klasse.php Abbildung 13.3 zeigt die von phpDocumentor generierte Dokumentation für unsere Klasse. Obwohl diese noch keine Codekommentare enthält, hat phpDocumentor bereits einige Informationen aus dem Code extrahieren können. So erhalten wir beispielsweise die Information, dass die Methode setzeVariable() als public deklariert ist und keinen Rückgabewert liefert. Abbildung 13.3. Von phpDocumentor erzeugte Dokumentation für eine Klasse ohne Codekommentare
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.code-documentation.phpdocumentor.html (2 von 6)07.06.2005 21:39:24
phpDocumentor
Wir fügen nun sukzessiv Codekommentare zum Quelltext der Klasse hinzu. In Beispiel 13.3 ist der Codekommentar-Block für die Klassendeklaration zu sehen. Hier geben wir eine Beschreibung zur Aufgabe der Klasse sowie ein Beispiel für ihre Verwendung an. Schließlich machen wir Angaben darüber, wer die Klasse programmiert hat und zu welchem Paket und Unterpaket sie gehört. Beispiel 13.3: Dokumentationskommentar für eine Klasse * * * @author * @package * @subpackage */ class Klasse { // ... } ?>
Sebastian Bergmann PSMP5 phpDocumentor
Beispiel 13.4 zeigt den Codekommentar für die Instanzvariable $variable. Durch die Angabe von @var string dokumentieren wir hierbei für phpDocumentor, dass die Instanzvariable vom Typ String ist. Beispiel 13.4: Dokumentationskommentar für eine Instanzvariable Beispiel 13.5 zeigt den Codekommentar für die Methode setzeVariable(). Mit @param string $parameter und @return string dokumentieren wir Typ und Zweck des Parameters sowie des Rückgabewertes. Beispiel 13.5: Dokumentationskommentar für eine Methode Dank der Codekommentare ist phpDocumentor nun in der Lage, ausführlichere Code-Dokumentation für unsere Klasse zu erzeugen (Abbildung 13.4). Abbildung 13.4. Von phpDocumentor erzeugte Dokumentation für eine Klasse mit Codekommentare
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.code-documentation.phpdocumentor.html (5 von 6)07.06.2005 21:39:25
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.code-documentation.phpdocumentor.html (6 von 6)07.06.2005 21:39:25
Weiter Doxygen
Doxygen
Zurück
Doxygen Kapitel 13. Code-Dokumentation
Weiter
Doxygen Auch wenn phpDocumentor das Standardwerkzeug für die Code-Dokumentation von PHP-Projekten ist, so lohnt sich dennoch ein Blick auf Alternativen. Doxygen ist der etablierte Standard für die C++-Code-Dokumentation und unterstützt unter anderem auch PHP. Die Verwendung von Doxygen gestaltet sich ein wenig aufwändiger als die von phpDocumentor. Mit doxygen -g ist zunächst für das zu dokumentierende Projekt eine Schablone für die Konfigurationsdatei (Doxyfile) zu erzeugen. Diese ist dann zu editieren, wobei Einstellungen wie Name und Version des Projektes ebenso vorzunehmen sind wie Detailgrad und Format der Ausgabe. Danach genügt ein einfacher Aufruf von doxygen in dem Verzeichnis, das die Datei Doxyfile enthält. Doxygen "versteht" dieselben Tags wie phpDocumentor, erzeugt jedoch Code-Dokumentation, die über die von phpDocumentor gebotene hinausgeht. Hierzu gehören vor allem die automatisch generierten UML-Klassen- und Kollaborationsdiagramme. Abbildung 13.5 zeigt beispielsweise die für den Konstruktor der Klasse PHPUnit2_Framework_TestCase erzeugte Dokumentation. Diese enthält unter anderem einen Aufrufgraph, der Informationen über die von der Methode aufgerufenen Methoden enthält. Abbildung 13.5. Dokumentation für den Konstruktor der Klasse PHPUnit2_Framework_TestCase
Abbildung 13.6 zeigt die Klassenhierarchie der Schnittstelle PHPUnit2_Framework_Test (siehe Kapitel 4), Abbildung 13.7 das UML-Klassendiagramm. Abbildung 13.6. Klassenhierarchie der Schnittstelle PHPUnit2_Framework_Test
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.code-documentation.doxygen.html (1 von 3)07.06.2005 21:39:26
Doxygen
Abbildung 13.7. UML-Klassendiagramm der Schnittstelle PHPUnit2_Framework_Test
Die Diagramme sind (dank HTML-Imagemap) klickbar, so dass man sich mit wenigen Klicks -- von Klasse zu Klasse, von Methode zu Methode -- durch die CodeDokumentation navigieren kann. http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.code-documentation.doxygen.html (2 von 3)07.06.2005 21:39:26
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.code-documentation.doxygen.html (3 von 3)07.06.2005 21:39:26
Nach oben Zum Anfang
Weiter Kapitel 14. Modellierung mit UML und MDA
Kapitel 14. Modellierung mit UML und MDA
Zurück
Kapitel 14. Modellierung mit UML und MDA Teil V. Werkzeuge für die Entwicklung von PHP-Projekten.
Weiter
Kapitel 14. Modellierung mit UML und MDA "A common mistake that people make when trying to design something completely foolproof was to underestimate the ingenuity of complete fools." --Douglas Adams
Einleitung Die Unified Modeling Language (UML) ist eine durch die Object Management Group (OMG) standardisierte graphische Sprache zur Beschreibung objektorientierter Modelle. Sie legt Bezeichner für die meisten Begriffe, die im Rahmen der Objektorientierung benötigt werden, sowie eine Notation für deren mögliche Beziehungen (beispielsweise Klasse-Elternklasse) fest. Neben den bereits im Laufe des Buches verwendeten Klassendiagrammen gibt es noch zwölf weitere Diagrammtypen in der aktuellen Version 2.0. Wichtig sind hierbei vor allem die Anwendungsfalldiagramme, Aktivitätsdiagramme und die Sequenzdiagramme. Für die weitere Betrachtung beschränken wir uns auf die Klassendiagramme, da diese die Grundlage für die PHP-Unterstützung der gezeigten UML-Werkzeuge bilden. Zurück Doxygen
ArgoUML und Poseidon for UML Kapitel 14. Modellierung mit UML und MDA
Weiter
ArgoUML und Poseidon for UML Für den Entwurf der Architektur eines Projektes bietet sich die Verwendung eines so genannten CASE-Werkzeugs (Computer Aided Software Engineering) an. Mit diesem erstellt man die entsprechenden UML-Diagramme und kann Code-Gerüste für die spätere Ausprogrammierung aus dem Modell generieren. ArgoUML ist ein populäres, in Java geschriebenes Open-Source-CASE-Werkzeug. Für uns ist ArgoUML interessant, da es die Generierung von PHP-4- und PHP-5-Code unterstützt. In Abbildung 14.1 sehen wir ein UML-Klassendiagramm für die Klasse BankAccount (siehe Kapitel 4). Abbildung 14.1. ArgoUML
Beispiel 14.1 zeigt ein aus dem UML-Modell generiertes Code-Gerüst. ArgoUML hat hierbei eine PHP-Klasse mit entsprechenden Methoden und Code-Kommentaren erzeugt. Für das Gerüst der Methode getBalance() wurde beispielsweise die Typinformation für den Rückgabewert (float) genutzt und in den Code überführt.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.uml-mda.uml.html (1 von 3)07.06.2005 21:39:30
ArgoUML und Poseidon for UML
Beispiel 14.1: Von ArgoUML generierter PHP-5-Code Die kommerzielle Variante von ArgoUML, Poseidon for UML, sieht schöner aus und bietet etliche Leistungsmerkmale, die die Open-Source-Fassung nicht bietet. Sie ist jedoch für die PHP-5-Programmierung derzeit noch nicht interessant, da sie nur PHP-4-Code generieren kann. Abbildung 14.2. Poseidon for UML
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.uml-mda.uml.html (3 von 3)07.06.2005 21:39:30
Nach oben Zum Anfang
Weiter UML2PHP
UML2PHP
Zurück
UML2PHP Kapitel 14. Modellierung mit UML und MDA
Weiter
UML2PHP Die modellgetriebene Entwicklung (englisch: Model Driven Architecture, MDA) geht einen Schritt weiter und erstellt nicht nur ein Code-Grundgerüst aus einem UML-Modell, sondern ein vollständiges Softwaresystem. MDA, welches ein weiterer OMGStandard ist, erweitert die UML hierzu zu einer formal eindeutigen Modellierungssprache. Das Modell ist von Plattform oder Programmiersprache unabhängig. Ein Generator erzeugt den Code für die jeweils gewünschte Zielplattform, beispielsweise Apache, MySQL und PHP. Erklärtes Ziel der modellgetriebenen Entwicklung ist die Programmierung auf einer abstrakteren Ebene als zuvor: Eine Geschäftslogik soll so nur einmal als MDA-Modell spezifiziert werden müssen. Durch Weiterentwicklung der Generatoren soll das MDA-Modell auch auf zukünftigen Plattformen in entsprechenden Code überführt werden können. UML2PHP ist das erste Werkzeug für die modellgetriebene Entwicklung mit PHP. In der ersten Stufe unterstützt UML2PHP die Generierung einer lauffähigen PHP-Anwendung aus den Klassendiagrammen eines (beispielsweise mit Poseidon for UML erstellten) UML-Modells. In späteren Versionen sollen auch die Anwendungsfall-, Aktivitäts- und Sequenzdiagramme des Modells berücksichtigt werden. Bei der Code-Generierung erzeugt UML2PHP für jede Klasse des UML-Modells eine Geschäftsobjekt-Klasse. Objekte dieser Klasse werden persistent (ähnlich wie bei Propel, siehe Kapitel 12) in einer relationalen Datenbank gehalten und können über automatisch erzeugte und verarbeitete Formulare angezeigt und editiert werden. Die generierte Anwendung nutzt eine mitgelieferte Klassenbibliothek. Diese übernimmt unter anderem Datenbankabstraktion, das Speichern von PHP-Objekten in einer relationalen Datenbank, Benutzer- und Rechteverwaltung sowie Formularverarbeitung und Session-Verwaltung. Abbildung 14.3 zeigt ein UML-Klassendiagramm für eine Rezeptsammlung. Für diese Sammlung verwalten wir eine Liste von Rezepten sowie eine Liste von Freunden, von denen wir die Rezepte erhalten haben. Abbildung 14.3. Klassendiagramm für die Rezeptsammlung
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.uml-mda.mda.html (1 von 6)07.06.2005 21:39:42
UML2PHP
Abbildung 14.4 zeigt den "Application Wizard" von UML2PHP. Hier laden wir das mit Poseidon for UML erstellte UML-Modell (Abbildung 14.3) und legen Einstellungen für Datenbankverbindung sowie Ausgabeverzeichnis fest. Durch Drücken des "Generate"-Knopfes wird eine vollständig funktionsfähige PHP-Anwendung erzeugt sowie die entsprechenden Tabellen in der angegebenen Datenbank angelegt. Abbildung 14.4. Code-Generierung mit UML2PHP
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.uml-mda.mda.html (2 von 6)07.06.2005 21:39:42
UML2PHP
Wenn wir die generierte Webanwendung im Browser öffnen, so können wir nach Eingabe der Logindaten ("admin", "admin") einen Datensatz für einen Freund (Abbildung 14.5) sowie ein Rezept (Abbildung 14.6) eingeben. Abbildung 14.5. Einen neuen Freund anlegen
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.uml-mda.mda.html (3 von 6)07.06.2005 21:39:42
UML2PHP
Das Rezept verknüpfen wir über das Feld "myFriend" mit dem zuvor angelegten Freund-Datensatz. Abbildung 14.6. Ein neues Rezept eingeben
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.uml-mda.mda.html (4 von 6)07.06.2005 21:39:42
UML2PHP
Nachdem wir einen Freund sowie ein Rezept in die Datenbank eingetragen haben, können wir uns die Daten im Überblick anschauen (Abbildung 14.7). Abbildung 14.7. Freunde und Rezepte im Überblick
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/tools.uml-mda.mda.html (5 von 6)07.06.2005 21:39:42
Anhang A. Installation von Apache 2.0, MySQL 4.1 und PHP 5.0
Anhang A. Installation von Apache 2.0, MySQL 4.1 und PHP 5.0 Teil Anhänge.
Zurück
Anhang A. Installation von Apache 2.0, MySQL 4.1 und PHP 5.0 Apache 2.0 1. Laden Sie die aktuelle Version des Apache 2.0 Webservers von der Homepage herunter. 2. Entpacken Sie die Distribution. tar xvfz httpd-2.0.XX.tar.gz 3. Konfigurieren Sie den Build-Prozess. cd httpd-2.0.XX ./configure --prefix=/usr/local/apache2 \ --enable-so 4. Starten Sie Build und Installation. make && make install 5. Der Apache-Webserver kann jetzt mit /usr/local/apache2/bin/apachectl start gestartet sowie mit /usr/local/apache2/bin/apachectl stop heruntergefahren werden. http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.installation.html (1 von 3)07.06.2005 21:39:44
Weiter
Anhang A. Installation von Apache 2.0, MySQL 4.1 und PHP 5.0
MySQL 4.1 1. Laden Sie die aktuelle MySQL-Version von der Homepage herunter. 2. Entpacken Sie die Distribution. tar xvfz mysql-4.1.X.tar.gz 3. Build und Installation cd mysql-4.1.X ./BUILD/compile-pentium-max make install ./scripts/mysql_install_db cp ./support-files/my-small.cnf /usr/local/mysql/var/my.cnf cp ./support-files/mysql.server /etc/init.d/mysql-4.1 chown -R mysql:daemon /usr/local/mysql 4. MySQL kann jetzt mit /etc/init.d/mysql-4.1 start gestartet sowie mit /etc/init.d/mysql-4.1 stop heruntergefahren werden. PHP 5.0 1. Laden Sie die aktuelle PHP-Version von der Homepage herunter. 2. Entpacken Sie die Distribution.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.installation.html (2 von 3)07.06.2005 21:39:44
Anhang A. Installation von Apache 2.0, MySQL 4.1 und PHP 5.0
tar xvfz php-5.0.X.tar.gz 3. Konfigurieren Sie den Build-Prozess. cd php-5.0.X ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-mysqli=/usr/local/mysql/bin/mysql_config --with-mysql=/usr/local/mysql --enable-bcmath --enable-soap --with-xsl
\ \ \ \ \
4. Starten Sie Build und Installation. make && make install 5. Kopieren Sie die Datei php.ini-recommended nach /usr/local/lib/php.ini, und passen Sie sie Ihren Wünschen gemäß an. Zurück Teil Anhänge.
Anhang C. Glossar Destruktor Der Destruktor ist eine spezielle Methode (__destruct()), die auf einem Objekt automatisch aufgerufen wird, wenn keine Variable mehr eine Referenz auf das Objekt enthält. Siehe auch Methode, Objekt, Referenz. Exemplar Siehe auch Objekt. Instanz Siehe auch Objekt. Instanzvariable Eine Instanzvariable bezeichnet eine Variable eines Objektes. Siehe auch Klasse, Objekt. Klasse Eine Klasse fasst Daten und die zugehörigen Operationen in einer Einheit zusammen. Sie dient als Bauplan für die Erzeugung von Objekten. Siehe auch Objekt. Konstruktor Der Konstruktor (__construct()) ist eine spezielle Methode, die automatisch bei der Erzeugung eines Objektes einer Klasse aufgerufen wird.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.glossary.html (1 von 3)07.06.2005 21:39:45
Anhang C. Glossar
Siehe auch Methode, Objekt. Methode Eine Methode ist eine Operation einer Klasse. Siehe auch Klasse, Objekt. Objekt Ein Objekt ist ein Exemplar (oder eine Instanz) einer Klasse. Siehe auch Klasse. Referenz Der new-Operator erzeugt ein neues Exemplar einer Klasse, ein Objekt. Als Rückgabe liefert er eine Referenz auf dieses neue Objekt, die in einer Variablen abgelegt wird. Über diese Variable kann das Objekt im Programm angesprochen werden. Siehe auch Klasse, Objekt. Schnittstelle Eine Schnittstelle ist eine vollständig abstrakte Klasse. Mit ihrer Hilfe können unterschiedliche Rollen eines Objektes modelliert werden. Siehe auch Klasse. Vererbung Vererbung erlaubt es, bestehenden Code zu erweitern, ohne ihn ändern oder duplizieren zu müssen. Hierbei erbt eine Kindklasse den Code einer Elternklasse und kann diesen ändern oder erweitern. Siehe auch Klasse. Zurück
Nach oben
Weiter
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.glossary.html (2 von 3)07.06.2005 21:39:45
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.glossary.html (3 von 3)07.06.2005 21:39:45
Anhang D. Stichwortverzeichnis
Zurück
Anhang D. Stichwortverzeichnis Teil Anhänge.
Weiter
Anhang D. Stichwortverzeichnis Symbole $this, Referenzen __autoload, Einleitung __call, Einleitung __clone, Referenzen __construct, Konstruktoren und Destruktoren __destruct, Konstruktoren und Destruktoren __get, Einleitung __set, Einleitung __sleep, Serialisierung von Objekten __toString, Einleitung __wakeup, Serialisierung von Objekten
A Abstrakte Fabrik, Abstrakte Fabrik Aggregation, Referenzen, Abstrakte Klassen und Schnittstellen ArrayAccess, Die Schnittstelle ArrayAccess Ausnahme, Fehlerbehandlung mit Ausnahmen
B Beobachter, Testfälle ausführen und zusammenfassen, Beobachter
C catch, Fehlerbehandlung mit Ausnahmen clone, Referenzen Code-Coverage, Code-Coverage-Analyse von PHP-Applikationen http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.index.html (1 von 6)07.06.2005 21:39:46
Anhang D. Stichwortverzeichnis
Codekommentare, phpDocumentor
D Datenbankabstraktion, Einleitung Deep Copy, Referenzen Dekorierer, Dekorierer Delegation, Referenzen, Abstrakte Klassen und Schnittstellen Design Pattern, Destruktor, Konstruktoren und Destruktoren Document Object Model (DOM),
E Entwurfsmuster, Exception, Fehlerbehandlung mit Ausnahmen Extreme Programming, Einleitung
F Fehlersignalisierung, Fehlerbehandlung mit Ausnahmen FilterIterator, Die Standard PHP Library (SPL), Dekorierer finally, Fehlerbehandlung mit Ausnahmen
G Garbage Collection, Referenzen Geheimnisprinzip, Klassen und Objekte
I in-band, Fehlerbehandlung mit Ausnahmen Instanzvariable, Klassen und Objekte Interface, Abstrakte Klassen und Schnittstellen Interzeptormethoden, Einleitung
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.index.html (2 von 6)07.06.2005 21:39:46
Anhang D. Stichwortverzeichnis
Introspektion, Die Reflection API Iterator, Einleitung, Die Iterator-Schnittstellen von PHP 5, Iterator IteratorAggregate, Die Iterator-Schnittstellen von PHP 5
K Kapselung, Klassen und Objekte Klasse, Klassen und Objekte Klasse, abstrakte, Abstrakte Klassen und Schnittstellen Klassendiagramm, Klassen und Objekte Klassenkonstante, Klassenmethoden, Klassenvariablen und Klassenkonstanten Klassenmethode, Klassenmethoden, Klassenvariablen und Klassenkonstanten Klassenvariable, Klassenmethoden, Klassenvariablen und Klassenkonstanten Klonen von Objekten, Referenzen Konstruktor, Konstruktoren und Destruktoren
L Lazy Initialization, __get LimitIterator, Die Standard PHP Library (SPL), Dekorierer
M Mehrfachvererbung, Abstrakte Klassen und Schnittstellen Methode, Klassen und Objekte Methode, abstrakte, Abstrakte Klassen und Schnittstellen Model Driven Architecture (MDA), UML2PHP
O Objekt, Klassen und Objekte Objektrelationales Mapping, Einleitung http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.index.html (3 von 6)07.06.2005 21:39:46
Anhang D. Stichwortverzeichnis
out-of-band, Fehlerbehandlung mit Ausnahmen
P parent, Vererbung Persistenz, Serialisierung von Objekten PHPUnit, Einleitung Polymorphie, Polymorphie private, Klassen und Objekte protected, Klassen und Objekte public, Klassen und Objekte
R RecursiveIteratorIterator, Die Klasse SimpleXMLIterator Refactoring, Einleitung Referenz, Referenzen Reflection API, Die Reflection API RelaxNG, Validieren von XML-Dokumenten
S Schablonenmethode, Schablonenmethode Schnittstelle, Abstrakte Klassen und Schnittstellen self, Klassenmethoden, Klassenvariablen und Klassenkonstanten Serialisierung, Serialisierung von Objekten set_exception_handler, Fehlerbehandlung mit Ausnahmen Shallow Copy, Referenzen Simple API for XML (SAX), Simple API for XML (SAX), Einen eigenen Namespace-Handler programmieren SimpleXML, SimpleXMLIterator, Die Klasse SimpleXMLIterator Singleton, Singleton Stack-Trace, Fehlerbehandlung mit Ausnahmen Standard PHP Library (SPL), Die Standard PHP Library (SPL) http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.index.html (4 von 6)07.06.2005 21:39:46
Anhang D. Stichwortverzeichnis
static, Klassenmethoden, Klassenvariablen und Klassenkonstanten Stellvertreter, __call, Stellvertreter Strategie, Strategie
T Test-First-Ansatz, Einleitung Testfall, Testfälle und Zusicherungen Testsuite, Testfälle ausführen und zusammenfassen throw, Fehlerbehandlung mit Ausnahmen try, Fehlerbehandlung mit Ausnahmen Type Hints, Klassen und Objekte, Abstrakte Klassen und Schnittstellen
U Unified Modeling Language (UML), Klassen und Objekte, Einleitung Unit Test, Einleitung
V Vererbung, Vererbung
W Web Service Description Language (WSDL), Einen Webdienst programmieren
X XML Schema, Validieren von XML-Dokumenten XML_Transformer, XPath, Die Klasse SimpleXMLElement, Formulieren von XPathAnfragen XSLT Transformations (XSLT),
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.index.html (5 von 6)07.06.2005 21:39:46
Anhang D. Stichwortverzeichnis
Z Zusicherungen, Testfälle und Zusicherungen Zustand, Klassen und Objekte Zurück Anhang C. Glossar
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.index.html (6 von 6)07.06.2005 21:39:46
Anhang E. Lizenz
Zurück
Anhang E. Lizenz Teil Anhänge.
Anhang E. Lizenz Text und Abbildungen dieser HTML-Dateien sind der Inhalt des Buchs "Professionelle Softwareentwicklung mit PHP 5" und urheberrechtlich geschützt. Ihre kommerzielle Weiterverbreitung in jeglicher Form und die Weiterverarbeitung in Druckform sind nicht erlaubt. Dies gilt auch für Übersetzungen. Ausdrücklich erlaubt ist die kostenlose Weitergabe des vollständigen Textes in der vorliegenden Form als HTML-Datei, inklusive dieses Urheberrechtsvermerks. Werden die vorliegenden Dateien im Rahmen dieser Erlaubnis auf einem Internet-Server oder als Teil einer kostenlosen CD-ROM verbreitet, wird um eine Information an Sebastian Bergmann gebeten. License These HTML files contain text and graphics of the book "Professionelle Softwareentwicklung mit PHP 5", published by dpunkt.verlag, Heidelberg, Germany. They are protected under copyright laws. Their commercial distribution in any form (electronic, printed, or other) is prohibited, as well as their non-commercial distribution in printed form. This restriction applies also to translations in any language. If you are interested in translating the content of these HTML files, please contact Sebastian Bergmann for further information. The non-commercial distribution of these texts and graphics in their original form as HTML files is expressively allowed, under the condition that this copyright text is included and the distribution is http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.license.html (1 von 2)07.06.2005 21:39:47
Anhang E. Lizenz
free of charge. If you wish to include these HTML files under this license on a CD ROM free of charge or if you want to make them freely available on a webserver, please send an email to Sebastian Bergmann. Zurück Anhang D. Stichwortverzeichnis
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/appendixes.license.html (2 von 2)07.06.2005 21:39:47
Geleitwort
Geleitwort Zurück
Weiter
Geleitwort Von Kristian Köhntopp. "Not that the story need be long, but it will take a long while to make it short." --Henry David Thoreau
Wenn man PHP als Sprache und als Plattform mit einem Wort beschreiben möchte, dann ist dieses Wort "Integration". Der Sprachkern von PHP und die Ausführungsumgebung sind darauf angelegt, beliebige Bibliotheken und neue Funktionen leicht und schnell in der Sprache zur Verfügung zu stellen: PHP ist wie die Borg in Star Trek - es fügt die Fertigkeiten anderer den eigenen hinzu, um Perfektion zu erreichen. Aber auch die Plattform PHP ist integrativ: PHP spricht eine ganze Reihe von Protokollen zum Datenaustausch und liest und schreibt nahezu alle dokumentierten Dateiformate und auch ein paar undokumentierte, für die lediglich proprietäre Bibliotheken zur Verfügung stehen. Diese Eigenschaften haben PHP zu dem bevorzugten Leim gemacht, mit dem ein Entwickler in einer Firma mit geringem Aufwand die unterschiedlichsten Daten und Prozesse zu einem gemeinsamen Ganzen zusammenkleben kann. Schließlich ist da noch die PHP-Anwendergemeinschaft. Für viele ist PHP die erste Programmiersprache, und sie sind genau wie die Sprache im Laufe der vergangenen Jahre mit der Sprache und ihren Fähigkeiten gewachsen. Anwender kommen von anderen Systemen zu PHP und bringen Wissen und Programmiertechniken mit, für die im Rahmen von http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/foreword.html (1 von 3)07.06.2005 21:39:48
Geleitwort
PHP Formulierungen und Ausdrucksmöglichkeiten gefunden werden müssen. Dieser Prozess ist manchmal schmerzhaft: Wie natürliche Sprachen auch leben Programmiersprachen stark von Redewendungen und Standardformulierungen für bestimmte Sachverhalte, und diese sind nicht nur von der Syntax, sondern auch von den dahinter stehenden Denkprozessen in der Gemeinschaft der Anwender einer Sprache bestimmt. Wenn also eine Welle von jungen Entwicklern mit einem Hintergrund in objektorientierter Programmierung auf eine Sprache wie PHP 4 trifft, dann kommt es zu Wachstumsschmerzen. Denn PHP 4 beherrschte zwar nominell Objektorientierung, war aber nicht ernsthaft auf den Einsatz von Methoden der OOP eingerichtet. Und so sind die Formulierungsmöglichkeiten sehr hölzern und unbeholfen, die PHP 4 solchen Entwicklern bietet. Eines der Hauptziele bei der Entwicklung von PHP 5 war folgerichtig, den Sprachkern zu erweitern, damit er die Techniken und Redewendungen von OOPEntwicklern angemessen darstellen kann. So wird mit PHP 5 zum ersten Mal eine Plattform für den LAMPEntwickler verfügbar, mit der sich zeitgemäße Entwurfsmethoden und OOP-Techniken mit vertretbarem Aufwand einsetzen lassen, und PHP hat auch diese Fertigkeiten den eigenen hinzugefügt. Es fehlt nur noch eine Anleitung, in der diese Fertigkeiten auf eine Weise beschrieben werden, die den Kern der Sache ohne Umschweife darstellt. Dieses Buch möchte diese Anleitung sein: Es hält sich nicht mit Dingen auf, die man in jedem beliebigen anderen Buch über PHP oder im wirklich guten Online-Handbuch zur Sprache nachlesen kann, sondern konzentriert sich darauf, objektorientierte Programmiertechniken und die neuen Möglichkeiten von PHP 5 zu integrieren. Demjenigen, für den PHP erste Programmiersprache ist, eröffnet dieses Buch einen guten Einstieg in die Objektorientierung. http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/foreword.html (2 von 3)07.06.2005 21:39:48
Geleitwort
Demjenigen, der von anderen Programmiersprachen zu PHP kommt, zeigt es die üblichen Redewendungen, mit denen PHPEntwickler objektorientierte Sachverhalte formulieren. Und weil Sebastian Bergmann sich die Zeit genommen hat, eine lange Geschichte kurz zu formulieren, haben beide Lesergruppen die Chance, diese Dinge zu lernen, ohne sich dabei mit dem 500 Seiten dicken Wälzer zu belasten, der entstanden wäre, wenn er dieses Buch in der Hälfte der Zeit fertig gestellt hätte. Karlsruhe, im Dezember 2004 Kristian Köhntopp
[1]
[1]
Kristian Köhntopp begann 1997 mit der Entwicklung von
Datenbank-getriebenen Websites in PHP/FI. Seine Arbeiten an PHPLIB haben die Entwicklung vieler anderer PHP-Bibliotheken und der OO-Features der Sprache beeinflußt. Ende 1999 stieß er die Einrichtung der deutschen USENET-Groups zu PHP an und pflegte die folgenden drei Jahre lang die FAQ zu diesen Gruppen. Derzeit arbeitet er bei der WEB.DE AG in Karlsruhe. Zurück Professionelle Softwareentwicklung mit PHP 5
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/foreword.html (3 von 3)07.06.2005 21:39:48
Einleitung
Einleitung Zurück
Weiter
Einleitung "You don't write for the money, because if you do, you're a monkey. You don't write for the fame, because if you do, you're a monkey. You don't even write because you like to write, because if you do, you're still a monkey. You write because to NOT write is suicide." --Stephen King
Über dieses Buch Die Geschichte dieses Buches beginnt im Jahr 2001. Die Arbeit an der Zend Engine 2, dem kompilierenden und ausführenden Kern von PHP 5, wurde gerade aufgenommen. Ich beginne damit, die Fähigkeiten des neuen Objektmodells auszuloten. Hierbei mache ich mir vor allem Gedanken darüber, wie diese neuen Sprachmerkmale die Entwicklung von komplexen Anwendungen erleichtern können. Schnell beginnen sich Fragen zur Umsetzung von Entwurfsmustern, die im Umfeld etablierter objektorientierter Systeme wie C++ oder Java entstanden sind, mit dem neuen Objektmodell von PHP 5 auf den PHP-Mailinglisten und in den PHPGruppen des Usenet zu wiederholen. Um diese und andere Fragen an zentraler Stelle zu beantworten, richte ich ein Projekt ("phpoopbook") beim Open-Source-Hoster SourceForge.net ein. Ziel dieses Projektes sollte eine Ideen- und CodebeispielSammlung über objektorientierte Programmierung mit PHP 5 sein. Im Laufe der folgenden Monate entsteht das Grundgerüst des Buches, das Sie, lieber Leser, heute in Händen halten.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/preface.html (1 von 4)07.06.2005 21:47:51
Einleitung
Auf dem LinuxTag 2002 komme ich mit René Schönfeldt vom dpunkt.verlag zusammen. Gemeinsam fassen wir den Entschluss, aus den bis dahin bei SourceForge.net liegenden Buchfragmenten ein "richtiges" Buch zu machen. Ein Vertrag wird unterschrieben, die Arbeit nimmt ihren Lauf. Da sich die Veröffentlichung von PHP 5 jedoch bis Sommer 2004 verzögert (ursprünglich war einmal das 2. Quartal 2002 geplant gewesen), dauert auch die Arbeit an diesem Buch länger als gedacht. In dieser Zeit wurden einige Umstrukturierungen am ursprünglichen Konzept nötig. Dieses hatte unter anderem einen Schwerpunkt bei der Programmierung objektorientierter PHPAnwendungen für einen Application Server (Script Running Machine, SRM) vorgesehen. Was dieses Buch sein möchte -- und was nicht Dieses Buch beschreibt erfahrenen PHP-Entwicklern den Weg in die neue, objektorientierte PHP-5-Welt. Sie lernen, welche professionellen Konzepte und Methoden in der Softwareentwicklung mit PHP zur Verfügung stehen und wie sie eingesetzt werden. Dieses Buch kann und möchte jedoch keine Einführung in PHP oder Themen der Softwaretechnologie wie objektorientierte Analyse und Design sein. Diagramme, die den Aufbau von Klassen oder die Interaktion zwischen Objekten veranschaulichen sollen, werden in der Notation der Unified Modeling Language (UML) dargestellt. Diese ist jedoch nicht Thema dieses Buches, auch wenn beispielsweise im Rahmen der Diskussion von Werkzeugen für die Modellierung von PHP-Applikationen auf Bestandteile der UML eingegangen wird. Das Gleiche gilt für die Themen Extreme Programming und Refactoring, die als Motivation für Unit Tests dienen. Wer mehr über objektorientierte Analyse und Design sowie UML lernen möchte, dem seien die Bücher [HitzKappel2003] und [Oestereich2004] empfohlen. [Fowler1999] ist das Standardwerk http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/preface.html (2 von 4)07.06.2005 21:47:51
Einleitung
zum Thema Refactoring. Aufbau dieses Buches Das Buch gliedert sich in fünf Hauptteile und einen Anhang. Der erste Teil ("Objektorientierte Programmierung") stellt neben den Grundlagen der objektorientierten Programmierung und deren Umsetzung in PHP die testgetriebene Entwicklung von PHPAnwendungen vor. Der zweite Teil ("Entwurfsmuster in PHP anwenden") ist den Entwurfmustern (englisch: Design Patterns) gewidmet. Der dritte Teil ("PHP-5-Programmierung") befasst sich mit der Verarbeitung von XML-Dokumenten, der Programmierung mit Webdiensten (SOAP) und der MySQLi-Erweiterung für die Arbeit mit MySQL 4.1 und MySQL 5.0. Der vierte Teil ("Fortgeschrittene Datenbankprogrammierung") widmet sich der Datenbankabstraktion mit Creole und der Speicherung von PHP-Objekten in einer relationalen Datenbank mit Propel. "Werkzeuge für die Entwicklung von PHP-Projekten" sind das Thema des fünften und letzten Teils. Im Zentrum der Diskussion der behandelten Themen stehen die zahlreichen Codebeispiele. Diese sind so angelegt, dass sie die Idee des jeweils behandelten Konzeptes kommunizieren und als Ausgangspunkt für das eigene Ausprobieren dienen. Die Codebeispiele werden begleitet von nicht zu viel, aber auch nicht zu wenig Erklärung. Der PHP-Code wird in diesem Buch in der Schrift Letter Gothic dargestellt. Programmaufrufe und Ausgaben von PHP-Programmen http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/preface.html (3 von 4)07.06.2005 21:47:51
Einleitung
erscheinen ebenfalls in dieser Schrift, werden jedoch in grauen Kästen hervorgehoben. Das Buch behandelt PHP 5. Die gezeigten Codebeispiele sind daher nicht mit früheren PHP-Versionen nachvollziehbar. Die Webseite zum Buch Auf der Website zum Buch finden Sie die Codebeispiele zum Herunterladen sowie drei Monate nach der Veröffentlichung eine als HTML gerenderte Fassung dieses Buches. Danksagungen Für sein Geleitwort und das technische Lektorat danke ich Kristian Köhntopp. Für sein technisches Lektorat des ersten Kapitels danke ich Pascal Costanza. Für sein technisches Lektorat für das MySQLi-Kapitel danke ich Georg Richter, dem Entwickler der MySQLi-Erweiterung. Für ihre Unterstützung bei der Arbeit an diesem Buch danke ich dem Team der dpunkt.verlag GmbH, besonders meinem Lektor René Schönfeldt. Für ihre Arbeit an der Zend Engine 2, dem Kern von PHP 5, danke ich Andi Gutmans, Zeev Suraski sowie Marcus Börger. Ohne sie gäbe es weder PHP 5 noch dieses Buch. Zurück Geleitwort
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/preface.html (4 von 4)07.06.2005 21:47:51
Teil I. Objektorientierte Programmierung.
Teil I. Objektorientierte Programmierung. Zurück
Weiter
Kapitel 1 Stellt die Grundlagen der objektorientierten Programmierung sowie deren Umsetzung in PHP vor. Kapitel 2 Behandelt mit den so genannten Interzeptoren spezielle Methoden, die bei bestimmten Ereignissen automatisch auf einem Objekt aufgerufen werden können. Kapitel 3 Zeigt die Integration des Iterator-Entwurfsmusters in die Programmiersprache selbst und mit FilterIterator, LimitIterator und SeekableIterator die drei grundlegenden Bestandteile der Standard PHP Library (SPL). Kapitel 4 Führt in die testgetriebene Entwicklung von PHPApplikationen mit Hilfe des PHPUnit2-Frameworks ein. Zurück Einleitung
Professionelle Softwareentwicklung mit PHP 5 Weiter
Professionelle Softwareentwicklung mit PHP 5 Objektorientierung. Entwurfsmuster. Modellierung. Fortgeschrittene Datenbankprogrammierung. Sebastian Bergmann Text und Abbildungen dieser HTML-Dateien sind der Inhalt des Buchs "Professionelle Softwareentwicklung mit PHP 5" (dpunkt. verlag, ISBN 3-89864-229-1) und urheberrechtlich geschützt. 1. Auflage 2005. Aktualisiert am 07.06.2005.
Widmung Dieses Buch ist meinen Eltern, Engelbert und Beatrice Bergmann, in Liebe gewidmet. Inhaltsverzeichnis Geleitwort Einleitung I. Objektorientierte Programmierung. 1. Grundlagen Einleitung Motivation Klassen und Objekte Polymorphie Referenzen Klassenmethoden, Klassenvariablen und Klassenkonstanten Konstruktoren und Destruktoren Vererbung Abstrakte Klassen und Schnittstellen Fehlerbehandlung mit Ausnahmen Serialisierung von Objekten http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/index.html (1 von 3)07.06.2005 21:48:00
Professionelle Softwareentwicklung mit PHP 5
Die Reflection API Migration von PHP 4 zu PHP 5 2. Interzeptormethoden Einleitung __autoload __get __set __call __toString 3. Iteratoren Einleitung Die Iterator-Schnittstellen von PHP 5 Die Standard PHP Library (SPL) Die Schnittstelle ArrayAccess 4. Testgetriebene Entwicklung mit PHPUnit Einleitung Testfälle und Zusicherungen Testfälle ausführen und zusammenfassen Automatische Generierung von Testfallklassen Code-Coverage-Analyse von PHP-Applikationen TestDox II. Entwurfsmuster in PHP anwenden. 5. Erzeugungsmuster Einleitung Abstrakte Fabrik Singleton 6. Strukturmuster Einleitung Dekorierer Stellvertreter 7. Verhaltensmuster Einleitung Beobachter Schablonenmethode Strategie Iterator III. PHP-5-Programmierung. 8. XML-Verarbeitung mit PHP Einleitung SimpleXML Simple API for XML (SAX) Document Object Model (DOM) XSL Transformations (XSLT) Objekte mit dem XML_Transformer ins Web bringen
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/index.html (2 von 3)07.06.2005 21:48:00
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/index.html (3 von 3)07.06.2005 21:48:00
Kapitel 1. Grundlagen
Kapitel 1. Grundlagen Teil I. Objektorientierte Programmierung.
Zurück
Weiter
Kapitel 1. Grundlagen "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." --Martin Fowler
Einleitung 2
PHP ist eine dynamisch getypte Programmiersprache [ ] , die sowohl prozedurale als auch objektorientierte Programmierung unterstützt. Für letztere bietet PHP ein klassenbasiertes Objektmodell an, das stark an das von C# oder Java angelehnt ist. Ein objektorientiertes PHP-Programm besteht aus einer Menge von PHP-Klassen, die den Regeln der PHP-Programmiersprache genügen und vom PHP-Interpreter übersetzt und ausgeführt werden. In diesem ersten Kapitel untersuchen wir zunächst die Grundlagen der objektorientierten Programmierung und betrachten deren Umsetzung in PHP.
[2]
In einer dynamisch getypten Programmiersprache ist der Typ eines Sprachobjektes nicht mit der Variable assoziiert, die das Sprachobjekt enthält. So kann der Typ des Inhalts einer Variablen in einer dynamisch getypten Programmiersprache beispielsweise von "String" zu "Integerzahl" geändert werden. In einer statisch getypten Programmiersprache ist dies nicht möglich, da bei der
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.html (1 von 2)07.06.2005 21:48:00
Kapitel 1. Grundlagen
Deklaration der Variable der Typ von Sprachobjekt vereinbart wird, den die Variable enthalten darf. Zurück Teil I. Objektorientierte Programmierung.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.html (2 von 2)07.06.2005 21:48:00
Kapitel 2. Interzeptormethoden
Zurück
Kapitel 2. Interzeptormethoden Teil I. Objektorientierte Programmierung.
Weiter
Kapitel 2. Interzeptormethoden "Are you quite sure that all those bells and whistles, all those wonderful facilities of your so called powerful programming languages, belong to the solution set rather than the problem set?" --Edsger Dijkstra
Einleitung Neben Konstruktor und Destruktor sowie den Methoden __sleep () und __wakeup() bietet PHP noch eine Reihe weiterer spezieller Methoden an, die für bestimmte Ereignisse automatisch aufgerufen werden. Da diese Methoden die entsprechenden Ereignisse in gewisser Weise "abfangen", nennt man sie Interzeptormethoden. PHP bietet die folgenden Interzeptormethoden an. Sie werden automatisch aufgerufen beim Zugriff auf nicht deklarierte Instanzvariablen und Methoden eines Objektes, beim Versuch, ein Objekt einer nicht deklarierten Klasse zu erzeugen, sowie bei der Typumwandlung eines Objektes in einen String. ●
__autoload($className) Wird aufgerufen, wenn ein Objekt der Klasse $className erzeugt werden soll, die Klasse aber nicht deklariert ist.
●
__get($memberName) Wird aufgerufen, wenn lesend auf die Instanzvariable $memberName eines Objektes zugegriffen wird, die Instanzvariable aber nicht gesetzt ist.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.interceptors.html (1 von 2)07.06.2005 21:48:02
Kapitel 2. Interzeptormethoden ●
__set($memberName, $value) Wird aufgerufen, wenn schreibend auf die Instanzvariable $memberName eines Objektes zugegriffen wird und sie vorher nicht gesetzt war. Der zweite Parameter $value enthält den Wert, den die Instanzvariable erhalten soll.
●
__call($methodName, $parameters) Wird aufgerufen, wenn eine nicht deklarierte Methode $methodName auf einem Objekt aufgerufen wird. Der zweite Parameter $parameters enthält die Parameter des Methodenaufrufes.
●
__toString() Wird aufgerufen, wenn eine Typumwandlung eines Objektes in einen String durchgeführt werden soll.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.interceptors.html (2 von 2)07.06.2005 21:48:02
Kapitel 3. Iteratoren
Zurück
Kapitel 3. Iteratoren Teil I. Objektorientierte Programmierung.
Weiter
Kapitel 3. Iteratoren "If the programmer can simulate a construct faster than a compiler can implement the construct itself, then the compiler writer has blown it badly." --Guy Steele
Einleitung Das Aufzählen oder Durchlaufen der Elemente einer Menge ist ein wiederkehrendes Problem. Beispiele für solche Mengen sind Arrays, die Zeilen einer Textdatei, die Elemente eines XMLDokumentes oder die Ergebniszeilen einer Datenbankabfrage. In PHP 3 erfolgte das Durchlaufen eines numerisch indizierten Arrays mit Hilfe einer for()-Schleife (Beispiel 3.1). Hierbei musste der Programmierer auf die Indexgrenzen achten. Beispiel 3.1: Iterieren von Arrays in PHP 3 1 2 3 4 5 6 7 8 9 10 Assoziative Arrays mussten in PHP 3 mit reset(), while(), list () und each() (Beispiel 3.2) verarbeitet werden. Beispiel 3.2: Iterieren von assoziativen Arrays in PHP 3
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.iterators.html (1 von 3)07.06.2005 21:48:02
Kapitel 3. Iteratoren
key: value In PHP 4 wurde mit foreach ein neuer Operator eingeführt, der die Arbeit mit assoziativen und numerisch indizierten Arrays vereinfachte und vereinheitlichte (Beispiel 3.3). Nun war es nicht mehr Aufgabe des Programmierers, sich um Dinge wie Indexgrenzen oder das Fortschreiten zum nächsten Element zu kümmern. Beispiel 3.3: Iterieren von Arrays in PHP 4 1 2 3 4 5 6 7 8 9 10 key: value Bereits in PHP 4 war es möglich, den foreach-Operator auf ein Objekt anzuwenden. In diesem Fall wurden die Instanzvariablen des Objektes wie ein assoziatives Array durchlaufen (Beispiel 3.4). Dies ist in PHP 5 weiterhin möglich, jedoch werden hierbei nur die öffentlichen Instanzvariablen berücksichtigt. Beispiel 3.4: Verwendung von foreach() mit Objekten a: 1 b: 2 An dieser Stelle wünschen wir uns ein Konzept, das die Vereinheitlichung von assoziativen und numerisch indizierten Arrays verallgemeinert und auf Objekte erweitert. Dieses Konzept finden wir im Entwurfsmuster (siehe Teil II. Entwurfsmuster in PHP anwenden) des Iterators, das wir im Folgenden diskutieren wollen. Ein Iterator ermöglicht den generischen Zugriff auf die Elemente einer Menge, ohne dass die Struktur der Menge oder die Implementierung der einzelnen Elemente bekannt sein muss. Bei den Elementen einer solchen Menge kann es sich beispielsweise um die Zeilen einer Textdatei, die Elemente eines XMLDokumentes oder die Ergebniszeilen einer Datenbankabfrage handeln. Zurück __toString
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.iterators.html (3 von 3)07.06.2005 21:48:02
Kapitel 4. Testgetriebene Entwicklung mit PHPUnit
Kapitel 4. Testgetriebene Entwicklung mit PHPUnit Teil I. Objektorientierte Zurück Weiter Programmierung.
Kapitel 4. Testgetriebene Entwicklung mit PHPUnit "The fewer tests you write, the less productive you are and the less stable your code becomes." --Erich Gamma
Einleitung Das Testen von Software ist wichtig. Doch obwohl dies allen Softwareentwicklern bewusst sein dürfte, verhalten sich die meisten nicht entsprechend. Sie testen ihre Software entweder gar nicht, oder erst, wenn es zu spät ist. Vorurteile und vorgeschobene Gründe wie die folgenden führen zu einem Teufelskreis, dem nur schwer zu entkommen ist: ● ● ●
●
"Ich habe keine Zeit zum Testen." "Testen von Software ist langweilig und stupide." "Mein Code ist praktisch fehlerfrei, auf jeden Fall gut genug." "Die Testabteilung testet. Die können das eh viel besser."
Im Extreme Programming, das zu den so genannten agilen oder leichtgewichtigen Software-Entwicklungsprozessen gehört, wird dieser Teufelskreis durchbrochen, und zwar durch die Forderung, den Test zuerst zu schreiben und danach den Code, auf den sich der Test bezieht (Test-First-Ansatz). Das Vertrauen in den Code wird erhöht, die Auswirkungen von Änderungen an einer Stelle auf den restlichen Code können schnell und zuverlässig überprüft werden. Darüber hinaus führt diese Vorgehensweise zu Einfachheit, Testbarkeit und Wartbarkeit des Codes. Das Schreiben von neuem Produktionscode gestaltet sich beim http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.phpunit.html (1 von 4)07.06.2005 21:48:03
Kapitel 4. Testgetriebene Entwicklung mit PHPUnit
Test-First-Ansatz in zwei Schritten: 1. Bevor neuer Produktionscode geschrieben wird, wird ein entsprechender Test geschrieben, der diesen Code motiviert. Dies sorgt einerseits dafür, dass es zu keinem Zeitpunkt Produktionscode gibt, für den kein Test existiert. Andererseits setzt sich der Programmierer beim Formulieren des Tests mit den Anforderungen an den zu schreibenden Code auseinander. 2. Es wird nur so viel Produktionscode geschrieben, wie es der Test verlangt. Mit anderen Worten: Läuft der Test, steht der Code. Ohne die automatisierte Ausführung von Entwicklertests auf Modulebene (englisch: Unit Tests), wie wir sie in diesem Kapitel diskutieren wollen, ist das Refactoring (deutsch: "neu herstellen") von Code nur schwer möglich. Martin Fowler definiert Refactoring als "den Prozess, ein Softwaresystem so zu ändern, dass sich das externe Verhalten nicht ändert, jedoch die innere Struktur verbessert wird". [Fowler1999] Hierzu gehören unter anderem Änderungen an der Struktur des Codes wie Umbenennung von Klassen und Methoden oder die Extraktion von Code einer Klasse in eine neue Klasse. Der Begriff des Unit Tests kommt ursprünglich aus der prozeduralen Programmierung. Dort entsprach die zu testende Programmeinheit einer Funktion oder Prozedur. In der objektorientierten Programmierung ist diese Definition weiter gefasst, so dass von einer einzelnen Methode, über eine gesamte Klasse bis hin zum gesamten System Programmeinheiten mit einem Unit Test getestet werden können. Unit Tests ermöglichen das ständige Refactoring von Code auf der Basis der folgenden Regeln: 1. Alle Unit Tests laufen.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.phpunit.html (2 von 4)07.06.2005 21:48:03
Kapitel 4. Testgetriebene Entwicklung mit PHPUnit
2. Der Code kommuniziert alle seine Designkonzepte. 3. Der Code enthält keine Redundanz. 4. Der Code enthält, unter Berücksichtigung der obigen Regeln, die geringstmögliche Anzahl an Klassen und Methoden. Erst automatisierte Tests machen die zum Erreichen des einfachsten Designs nötigen Änderungen am Code sinnvoll durchführbar. Ohne sie müsste jede Methode einer jeden Klasse von Hand getestet werden, wenn der Code einer Klasse geändert wurde. In der Java-Welt bildet JUnit den De-facto-Standard unter den Frameworks für Unit Tests. JUnit definiert eine allgemeine Struktur für Testfälle, gibt dem Entwickler die nötigen Werkzeuge an die Hand, um diese auszuführen, und übernimmt so einen großen Teil der Arbeit. Unter dem Namen PHPUnit habe ich eine PHP-Portierung von JUnit entwickelt, die über PEAR als OpenSource-Software bezogen werden kann. Test-Frameworks wie PHPUnit und JUnit erlauben die strikte Trennung von Produktionscode und Testcode. Tests können gruppiert werden, die Ausführungsreihenfolge hat keinen Einfluss auf das Ergebnis der einzelnen Tests. Neben PHPUnit2, der aktuellen Version von PHPUnit für PHP 5, gibt es mit PHPUnit eine Version für PHP 4, die nicht so umfangreich wie die Implementierung für PHP 5 ist und nicht mehr weiterentwickelt wird. PHPUnit2 enthält das auf JUnit basierte Unit-Test-Framework sowie ein Frontend für die Verwendung von der Kommandozeile. Neben der Funktionalität von JUnit bietet PHPUnit2 unter anderem auch die Funktionen von junitour für unvollständige Tests und TestDox für die agile Dokumentation. Die Installation des PHPUnit2-Paketes gestaltet sich dank des PEAR-Installers recht komfortabel:
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.phpunit.html (3 von 4)07.06.2005 21:48:03
Kapitel 4. Testgetriebene Entwicklung mit PHPUnit
Abbildung 4.1. Das PHPUnit2-Paket installieren pear install --alldeps PHPUnit2 Im Folgenden betrachten wir die von PHPUnit2 bereitgestellten Klassen und werden sehen, wie mit ihnen Unit Tests geschrieben und automatisiert ausgeführt werden können. Zurück Die Schnittstelle ArrayAccess
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.phpunit.html (4 von 4)07.06.2005 21:48:03
Motivation
Zurück
Motivation Kapitel 1. Grundlagen
Weiter
Motivation Wir wollen uns zunächst fragen, warum wir eine PHP-Anwendung überhaupt objektorientiert entwerfen wollen und nicht den vermeintlich einfacheren Weg der prozeduralen Programmierung wählen. Für Code, der für die Verwendung durch andere Entwickler bestimmt ist oder von mehreren Programmierern erstellt wird, sollte vor dem eigentlichen Schreiben zunächst ein Design erstellt werden. Der Sinn eines solchen Designs ist es, gut organisierten und konsistenten Code zu schreiben, der einfach zu erweitern und zu warten ist. Ende der 60er, Anfang der 70er Jahre des vergangenen Jahrhunderts hielten neue Sprachkonstrukte, und mit ihnen ein neues Programmierparadigma, Einzug in Programmiersprachen wie Simula oder Smalltalk. Sie sollten die Formulierung des Designs in der Programmiersprache gegenüber dem etablierten prozeduralen Ansatz erleichtern. So leistet der prozedurale Code in Beispiel 1.1 zwar die von ihm erwartete Aufgabe, ist aber in mehrerlei Hinsicht "unschön". An eine Wiederverwendung des Codes im eigentlichen Sinne von "einmal schreiben, mehrfach verwenden" ist allerdings nicht zu denken. Höchstens durch Duplizierung und Anpassung an den neuen Kontext kann er an anderer Stelle eingesetzt werden. Beispiel 1.1: Zugriff auf eine MySQL-Datenbank ohne objektorientierte Konzepte Wünschenswert wäre eine wiederverwendbare Einheit, die die http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.motivation.html (1 von 2)07.06.2005 21:48:04
Motivation
Datenbankverbindung und die mit ihr assoziierten Operationen zusammenfasst. Ist sie einmal mit den Verbindungsparametern initialisiert, kümmert sich diese Einheit für ihren Verwender unsichtbar um buchhalterische Aufgaben wie Verbindungsaufund -abbau, Verarbeitung von Anfragen und dergleichen mehr. Um eine solche Einheit programmiertechnisch umsetzen zu können, bedarf es eines zusätzlichen Sichtbarkeitsbereiches (englisch: scope) neben dem von Hauptprogramm und Prozedur. Dieser neue Sichtbarkeitsbereich soll Variablen und Prozeduren, die diese Variablen manipulieren, in einer Einheit zusammenfassen. Zurück Kapitel 1. Grundlagen
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.motivation.html (2 von 2)07.06.2005 21:48:04
Klassen und Objekte
Zurück
Klassen und Objekte Kapitel 1. Grundlagen
Weiter
Klassen und Objekte In der objektorientierten Programmierung entspricht die Klasse dem gesuchten Konstrukt für das Zusammenfassen von Daten und Operationen in einer Einheit. In der Fachsprache der Objektorientierung nennt man die Daten die Instanzvariablen und die Operationen die Methoden der Klasse. Eine Klasse dient als Bauplan für die Erzeugung von Objekten während der Laufzeit eines objektorientierten Programmes. Dieses besteht aus einem dynamischen Geflecht solcher Objekte. ●
Die Belegung der Instanzvariablen eines Objektes mit bestimmten Werten definiert dessen aktuellen Zustand. Jedem Objekt lässt sich eine Klasse zuordnen, nach deren Vorgaben es erzeugt wurde. Den Objekten einer Klasse ist ihre Funktion gemeinsam, da sie über dieselben Methoden verfügen. Sie unterscheiden sich nur in ihrem Zustand voneinander. ●
Eine Methode definiert eine Operation, die auf dem Objekt ausgeführt werden kann. Sie ist mit dem Begriff der Prozedur vergleichbar. Ein wesentlicher Aspekt der objektorientierten Programmierung liegt in der Autonomie der Objekte für die Entscheidung, welche Methode für die Reaktion auf eine Nachricht von außen aufgerufen wird. Der Begriff "Methodenaufruf" (in Analogie zum Prozeduraufruf in der prozeduralen Programmierung) ist zu unpräzise. Es gilt zwischen dem Senden einer Nachricht an ein Objekt (durch das Aufrufen einer Methode) und der Ausführung einer Methode durch das Objekt zu unterscheiden: Welche Methode tatsächlich ausgeführt wird, entscheidet das Objekt. Dieses Zusammenfassen von Daten und Operationen in einer Einheit wird Kapselung genannt und bildet die Grundlage der objektorientierten Programmierung. Mit diesem Geheimnisprinzip wird die Trennung von Nutzungs- und Implementierungsschicht, von Realisierung und Nutzung verfolgt: Ein Entwickler, der eine Klasse eines anderen Entwicklers verwenden möchte, braucht die internen Abläufe der Klasse nicht zu kennen, er verwendet nur die vereinbarte Schnittstelle. Zu diesem Zweck wird den Instanzvariablen und Methoden einer Klasse bei ihrer Deklaration eine von drei möglichen Zugreifbarkeiten zugewiesen: ●
private kennzeichnet die lokale Zugreifbarkeit. Auf das Element kann nur in der
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.classes-objects.html (1 von 4)07.06.2005 21:48:33
Klassen und Objekte
●
umgebenden Klasse zugegriffen werden. protected kennzeichnet die eingeschränkte Zugreifbarkeit. Auf das Element kann nur in der umgebenden Klasse und deren Kindklassen zugegriffen werden.
●
public kennzeichnet die allgemeine Zugreifbarkeit.
Wird keines der drei Schlüsselwörter private, protected und public bei der Deklaration einer Instanzvariablen beziehungsweise einer Methode angegeben, so wird implizit die allgemeine Zugreifbarkeit (public) angenommen. Nicht verwechseln sollte man das Geheimnisprinzip mit einem Sicherheitskonzept im Sinne einer Zugriffskontrolle, die sicherstellt, dass nur berechtigte Objekte auf bestimmte Instanzvariablen und Methoden zugreifen dürfen. Dies ist hier nicht gemeint. Vielmehr sollen für die Verwendung der Klasse unwesentliche Details vor dem Verwender der Klasse verborgen werden, wie beispielsweise die Verwaltung von Ressourcen. Es geht nicht darum, dass er diese Details nicht wissen darf, sondern er braucht sie nicht zu wissen. Dies erlaubt es dem Programmierer einer Klasse, Implementierungsdetails zu ändern, ohne dass der Verwender der Klasse Änderungen an seinem Code vornehmen muss. Die Deklaration einer Methode als public kommt somit einer Festlegung gleich, während die Implementierung von als protected oder private deklarierten Methoden in einer späteren Version oder Unterklasse (siehe „Vererbung“) geändert werden kann. Die Syntax für die Deklaration von Klassen, Instanzvariablen und Methoden betrachten wir in diesem Kapitel am Beispiel einer Klasse für den Zugriff auf eine MySQL-Datenbank. Die Minimalfunktionalität, die wir von einer solchen Klasse erwarten, umfasst Methoden für den Auf- und Abbau einer Verbindung zum Datenbankserver sowie Methoden für die Ausführung von Anfragen und die Verarbeitung von Ergebniszeilen, die von einer Anfrage geliefert werden. Um die Struktur von Klassen, die Interaktionen zwischen Objekten oder die Abläufe innerhalb einer Methode zu illustrieren, verwenden wir Diagramme in der Notation der Unified Modeling Language (UML). Eine Klasse wird in UML beispielsweise als Rechteck dargestellt, das durch horizontale Linien in drei Bereiche aufgeteilt ist. Der obere Bereich beinhaltet neben dem Klassennamen (fett) optionale Informationen, beispielsweise über die Paketzugehörigkeit der Klasse. Die beiden anderen Bereiche sind den Instanzvariablen und Methoden der Klasse vorbehalten. Die Zugreifbarkeit von Instanzvariablen und Methoden wird durch Voranstellen von + (public), # (protected) und - (private) ausgedrückt. Abbildung 1.1 zeigt ein UML-Klassendiagramm für unser Beispiel. Abbildung 1.1. Eine Klasse für den Zugriff auf eine MySQL-Datenbank
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.classes-objects.html (2 von 4)07.06.2005 21:48:33
Klassen und Objekte
Die Implementierung dieser Klasse in PHP zeigt Beispiel 1.2. Das Beispiel verwendet die Pseudovariable $this, die wir im Abschnitt über Referenzen genauer betrachten werden. Die Verwendung der Klasse wird in Beispiel 1.3 demonstriert. Beispiel 1.2: Eine Klasse für den Zugriff auf eine MySQL-Datenbank Beispiel 1.3: Verwendung der MySQL-Klasse Bei der Deklaration von Methoden erlaubt PHP die Angabe eines Klassen- oder Schnittstellennamens für als Parameter übergebene Objekte. Im Gegensatz zu statisch getypten Programmiersprachen erfolgt die Typprüfung jedoch nicht zum Zeitpunkt der Kompilierung, sondern erst zur Laufzeit. Diese so genannten Type Hints ersparen dem Programmierer Schreibarbeit, wie an Beispiel 1.4 und Beispiel 1.5 zu erkennen ist. Beispiel 1.4: Typprüfung mit Type Hints Beispiel 1.5: Typprüfung mit dem instanceof-Operator Beispiel 1.4 und Beispiel 1.5 sind semantisch äquivalent und unterscheiden sich nur in der Art der Typprüfung durch die Type Hints beziehungsweise den instanceof-Operator. Zurück Motivation
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.classes-objects.html (4 von 4)07.06.2005 21:48:33
Weiter Polymorphie
Polymorphie
Zurück
Polymorphie Kapitel 1. Grundlagen
Weiter
Polymorphie Mit dem Prinzip der Polymorphie (Vielgestaltigkeit) wird ein dynamisches Verhalten von Methoden verfolgt, das von Anzahl und Typ der übergebenen Parameter abhängt. Im Falle einer dynamisch getypten Programmiersprache wie PHP gestaltet sich dies jedoch anders als in einer statisch getypten Programmiersprache wie beispielsweise Java. Für unterschiedliche Anzahl oder Typen der erwarteten Parameter einer Methode schreibt man beispielsweise in Java mehrere Methoden mit dem gleichen Namen. Beispiel 1.6: Polymorphie in Java class Klasse { public void methode(String variable) { System.out.println("Ein String wurde übergeben."); } public void methode(int variable) { System.out.println("Ein Integerwert wurde übergeben."); } }
In PHP ist die Deklaration von mehreren Methoden des gleichen Namens nicht vorgesehen. Polymorphes Verhalten von Methoden kann in PHP auf eine der folgenden Arten erreicht werden: ●
●
●
Eine Methode kann wegen der dynamischen Typisierung einen Parameter akzeptieren, der unterschiedliche Typen enthalten darf. Eine Methode kann eine variable Anzahl an Parametern akzeptieren, indem optionale Parameter mit Standardwerten versehen und an das Ende der Parameterliste gesetzt werden. Häufig verwendet man ein assoziatives Array als einzigen Parameter einer Methode. Dies ermöglicht eine variable Anzahl an (benannten) Parametern für die Methode, deren Reihenfolge aufgrund der Assoziativität beliebig sein kann.
Beispiel 1.7: Polymorphie in PHP
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.polymorphism.html (1 von 2)07.06.2005 21:48:34
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.polymorphism.html (2 von 2)07.06.2005 21:48:34
Weiter Referenzen
Referenzen
Zurück
Referenzen Kapitel 1. Grundlagen
Weiter
Referenzen Der new-Operator erzeugt ein neues Exemplar einer Klasse, ein Objekt. Als Rückgabe liefert er eine Referenz auf dieses neue Objekt. Diese Referenz wird in einer Variablen abgelegt. Über diese Variable kann das Objekt im Programm angesprochen werden. Der PHP-Interpreter unterscheidet Objekte anhand einer eindeutigen ID, die er beim Anlegen des Objektes vergibt. Um zu testen, ob zwei Variablen dasselbe Objekt referenzieren, kann der Operator === verwendet werden. Beispiel 1.8: Überprüfung der Objektidentität mit dem === Operator $a und $b referenzieren dasselbe Objekt. Enthält keine Variable mehr eine Referenz auf ein Objekt, so wird es gelöscht und der belegte Speicher wird freigegeben (Garbage Collection). Eine besondere Referenz enthält die Pseudovariable $this. Über diese kann ein Objekt auf seine eigenen Instanzvariablen und Methoden zugreifen. So wird in Beispiel 1.9 die Instanzvariable $variable des Objektes gesetzt, das durch die Variable $objekt referenziert wird. Beispiel 1.9: Verwendung der Pseudovariablen $this Das Ablegen einer Referenz auf ein anderes Objekt in einer Instanzvariablen eines Objektes nennt man Aggregation. Man sagt in solch einem Fall, dass ein Objekt ein anderes aggregiert. Leitet ein Objekt einen Methodenaufruf an ein aggregiertes Objekt weiter, so spricht man von Delegation. Manchmal möchte man anstelle einer Referenz eine Kopie eines Objektes verwenden. Beispielsweise wenn einer Methode ein Objekt als Parameter übergeben wird, man dieses Objekt aber nicht nach außen sichtbar verändern möchte. Mit dem clone-Operator kann man eine solche Kopie eines Objektes erzeugen.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.references.html (1 von 3)07.06.2005 21:48:35
Referenzen
Die Anwendung des clone-Operators auf ein Objekt erzeugt eine exakte Kopie desselben und liefert eine Referenz auf dieses neue Objekt. Beispiel 1.10: Klonen von Objekten $original und $kopie referenzieren nicht dasselbe Objekt. Wird keine exakte Kopie eines Objektes gewünscht, so kann der Kopiervorgang in der entsprechenden Klasse mit einer __clone-Methode angepasst werden. Innerhalb dieser Methode zeigt die Pseudovariable $this bereits auf die Kopie des Originalobjektes, die mit den Instanzvariablen desselben initialisiert wurde. Die Klasse Connection aus Beispiel 1.11 kapselt neben den Zugangsdaten für eine MySQLSerververbindung auch eine Ressource, die eine bestehende Verbindung repräsentiert. Die definierte __clone-Methode baut nach dem Klonen eines Objektes der Klasse Connection eine neue Verbindung zur Datenbank auf und benutzt hierzu die aus dem Originalobjekt kopierten Verbindungsdaten. Beispiel 1.11: Den Kopiervorgang eines Objektes anpassen Das Anpassen des Kopiervorgangs mit einer __clone-Methode ist ebenfalls notwendig, wenn das zu kopierende Objekt ein anderes Objekt aggregiert. Ohne eine Anpassung des Kopiervorgangs würde nämlich die entsprechende Instanzvariable der Kopie eine Referenz auf das vom Original aggregierte Objekt enthalten (Shallow Copy). Beispiel 1.12 zeigt eine __clone-Methode, die eine so genannte Deep Copy erzeugt. Hierbei wird das aggregierte Objekt kopiert, und nicht die Referenz auf dieses. Beispiel 1.12: Implementieren von Deep-Copy mit __clone() Original und Kopie aggregieren nicht dasselbe Objekt. Möchte man erreichen, dass nur Methoden des Objektes selbst dieses klonen dürfen, so ist die __clone-Methode als protected zu deklarieren. Soll das Klonen eines Objektes vollständig unterbunden werden, ist die __clone-Methode als final private zu deklarieren. Zurück Polymorphie
Nach oben Zum Anfang
Weiter Klassenmethoden, Klassenvariablen und Klassenkonstanten
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.references.html (3 von 3)07.06.2005 21:48:35
Klassenmethoden, Klassenvariablen und Klassenkonstanten
Zurück
Klassenmethoden, Klassenvariablen und Klassenkonstanten Kapitel 1. Grundlagen
Weiter
Klassenmethoden, Klassenvariablen und Klassenkonstanten Neben den bislang betrachteten Methoden, die auf einem Objekt aufgerufen werden, gibt es als Alternative Klassenmethoden, auch statische Methoden genannt. Sie werden mit dem Schlüsselwort static als solche ausgezeichnet. Diese Methoden können ausgeführt werden, ohne dass ein Objekt der Klasse benötigt wird. Eine Klassenmethode wird mit Klasse::methode() aufgerufen. Beispiel 1.13: Klassenmethoden Klasse::methode() aufgerufen. In einer als static deklarierten Methode kann die Pseudovariable $this nicht verwendet werden, da Klassenmethoden außerhalb des Objektkontexts operieren. Zusätzlich zu den Instanzvariablen gibt es noch zwei weitere Möglichkeiten, Daten im Kontext einer Klasse zu speichern. ●
Klassenvariablen, auch statische Variablen genannt, werden mit dem Schlüsselwort static deklariert. Die Änderung des Inhalts einer solchen Variablen in einem Objekt ändert den Inhalt in allen Objekten der zugehörigen Klasse. Der Zugriff auf eine Klassenvariable erfolgt über Klassenname:: $variable.
●
Klassenkonstanten entsprechen Nur-Lese-Klassenvariablen, die immer öffentlich (public) zugreifbar sind und mit dem Schlüsselwort const deklariert werden. Der Zugriff auf eine Klassenkonstante erfolgt über Klassenname::konstante.
Beispiel 1.14: Klassenkonstanten und -variablen Klasse::konstante = 0 $a->inc() = 1 $b->inc() = 2 Erfolgt der Zugriff auf eine Klassenmethode, eine Klassenvariable oder eine Klassenkonstante aus einer Methode derselben Klasse heraus, so kann alternativ self::methode(), self::$variable beziehungsweise self::konstante verwendet werden. Das Schlüsselwort self bezieht sich stets auf den Sichtbarkeitsbereich der zur Methode gehörigen Klasse. In einem UML-Klassendiagramm werden Klassenmethoden und Klassenvariablen unterstrichen, um sie von den Instanzmethoden und Instanzvariablen abzusetzen. Zurück Referenzen
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.static.html (2 von 2)07.06.2005 21:48:36
Konstruktoren und Destruktoren
Zurück
Konstruktoren und Destruktoren Kapitel 1. Grundlagen
Weiter
Konstruktoren und Destruktoren Der Zugriff auf die Datenbank wird bereits durch die Klasse aus Beispiel 1.2 deutlich vereinfacht. Wir wollen nun den Aufruf der Methoden connect() und disconnect() automatisieren. Bei der Erzeugung eines Objektes der Klasse soll automatisch eine Verbindung zum Datenbankserver aufgebaut werden. Wird das Objekt nicht mehr benötigt, so soll diese Verbindung automatisch abgebaut werden. Hiermit werden weitere Details vor dem Verwender der Klasse verborgen, die er nicht kennen muss. Für solche Automatismen bei Erzeugung und Freigabe eines Objektes gibt es die speziellen Methoden Konstruktor und Destruktor. In PHP hat die Konstruktormethode den Namen __construct. Sie kann eine beliebige Anzahl von Parametern akzeptieren, einen Rückgabewert kann sie jedoch nicht zurückgeben. Sie wird nach Erzeugung und Initialisierung (Vorbelegung der Instanzvariablen) des Objektes auf diesem aufgerufen. Beispiel 1.15 zeigt die Implementierung eines Konstruktors für unsere Datenbankklasse, der die für einen connect()-Aufruf nötigen Parameter akzeptiert und diese an die entsprechende Methode weiterleitet. Beispiel 1.15: Konstruktor für die MySQL-Klasse Aus Kompatibilitätsgründen zu älteren Versionen wird aber auch eine Methode mit dem Namen der Klasse als Konstruktor akzeptiert. Im Falle eines Fehlers, beispielsweise bei fehlerhaften Zugangsdaten für eine Datenbankverbindung, kann die Konstruktormethode über das Auslösen einer Ausnahme (siehe „Fehlerbehandlung mit Ausnahmen“) abgebrochen werden. Die Ausführung des new-Operators im aufrufenden Kontext schlägt dann fehl und die Ausnahme kann dort entsprechend behandelt werden. Wird die Konstruktormethode als protected deklariert, so können nur Methoden
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.constructor-destructor.html (1 von 2)07.06.2005 21:48:36
Konstruktoren und Destruktoren
derselben Klasse ein Objekt der Klasse erzeugen. Der PHP-Interpreter ruft die Destruktormethode auf einem Objekt auf, wenn keine Variable mehr eine Referenz auf dieses enthält.
[3]
Der Aufruf erfolgt vor der Freigabe des von dem Objekt belegten Speichers, so dass der Zugriff auf Instanzvariablen in der Destruktormethode noch möglich ist. Die Destruktormethode trägt in PHP den Namen __destruct. Sie akzeptiert keine Parameter und kann ebenfalls kein Ergebnis zurückliefern. Beispiel 1.16 zeigt einen Destruktor, der bei seinem Aufruf disconnect ausführt und somit die mit dem Objekt assoziierte Datenbankverbindung schließt. Beispiel 1.16: Destruktor für die MySQL-Klasse Beispiel 1.17: Verwendung der um Konstruktor und Destruktor erweiterten Klasse
[3]
Dies stimmt leider nicht ganz, da eine Garbage Collection mit Reference Counting, wie sie der PHP-Interpreter verwendet, nicht immer direkt ermitteln kann, wann ein Objekt nicht mehr referenziert wird. Zurück Klassenmethoden, Klassenvariablen und Klassenkonstanten
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.constructor-destructor.html (2 von 2)07.06.2005 21:48:36
Weiter Vererbung
Vererbung
Vererbung Kapitel 1. Grundlagen
Zurück
Weiter
Vererbung Vererbung erlaubt es, bestehenden Code zu erweitern, ohne ihn ändern oder duplizieren zu müssen. PHP unterstützt hierbei die klassenbasierte Einfachvererbung, bei der eine so genannte Kindklasse sämtliche als public und protected deklarierten Instanzvariablen und Methoden von ihrer Elternklasse 4
übernimmt (erbt) [ ] . Die Kindklasse kann diese überschreiben sowie neue Instanzvariablen und Methoden definieren. Die Vererbungsbeziehung einer Kindklasse zu ihrer Elternklasse wird durch das extends-Schlüsselwort in der Klassendeklaration ausgedrückt. Eine Klasse hat in PHP maximal eine Elternklasse, sie kann jedoch beliebig viele Kindklassen besitzen. Mit dem Schlüsselwort final markierte Methoden der Elternklasse können in der Kindklasse nicht redefiniert werden, als final markierte Klassen können per Vererbung nicht erweitert werden. Betrachten wir als Beispiel die Erweiterung der Klasse DB_MySQL um die Serverkonfiguration für ein spezielles Projekt. Hierzu müssen wir lediglich eine Klasse MyProject_DB als Kindklasse von DB_MySQL einführen, deren Konstruktor wir dann entsprechend redefinieren. Abbildung 1.2 zeigt ein entsprechendes UMLKlassendiagramm. Der Pfeil symbolisiert die Vererbung, die Kindklasse zeigt auf ihre Elternklasse. Abbildung 1.2. Für ein Projekt spezialisierte, von DB_MySQL abgeleitete Klasse
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.inheritance.html (1 von 3)07.06.2005 21:48:37
Vererbung
Beispiel 1.18: Für ein Projekt spezialisierte, von DB_MySQL abgeleitete Klasse Durch die Möglichkeit, dem Konstruktor von MyProject_DB eine SQL-Anfrage zu übergeben, reduziert sich der vom Verwender der Klasse zu schreibende Code auf ein Minimum. Beispiel 1.19 zeigt, wie die abgeleitete Klasse den wiederkehrenden Code für SQL-Anfragen und die Verarbeitung ihrer Ergebniszeilen auf ein Minimum reduziert. Und sollten sich die Zugangsdaten für den MySQL-Server ändern, so müssen diese nur an einer Stelle aktualisiert werden. Dies erhöht zusätzlich die Wartbarkeit des Codes. Beispiel 1.19: Verwendung der abgeleiteten Klasse
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.inheritance.html (2 von 3)07.06.2005 21:48:37
Vererbung
Wird in einer abgeleiteten Klasse keine Konstruktor- beziehungsweise DestruktorMethode deklariert, so wird implizit die entsprechende Methode der Elternklasse aufgerufen. Andernfalls wird die Methode der Kindklasse aufgerufen, ohne dass die entsprechende Methode der Elternklasse implizit aufgerufen wird. Diese kann bei Bedarf jedoch explizit über parent::__construct() beziehungsweise parent:: __destruct() aufgerufen werden. Beispiel 1.20: Verhalten von Konstruktor- und Destruktormethode in abgeleiteten Klassen Elternklasse::__construct() aufgerufen. Kindklasse::__construct() aufgerufen. Elternklasse::__destruct() aufgerufen.
[4]
Man sagt auch, dass die Kindklasse von der Elternklasse abgeleitet wird und nennt die Kindklasse auch abgeleitete Klasse. Zurück Konstruktoren und Destruktoren
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.inheritance.html (3 von 3)07.06.2005 21:48:37
Abstrakte Klassen und Schnittstellen
Zurück
Abstrakte Klassen und Schnittstellen Kapitel 1. Grundlagen
Weiter
Abstrakte Klassen und Schnittstellen Neben den bislang betrachteten konkreten Methoden erlaubt PHP auch die Deklaration so genannter abstrakter Methoden. Im Gegensatz zu konkreten Methoden enthalten diese nur die Signatur (Name der Methode, Anzahl und Namen der Parameter). Die Implementierung einer abstrakten Methode erfolgt erst in einer abgeleiteten Klasse. Eine Klasse, die abstrakte Methoden enthält, wird auch abstrakte Klasse genannt. Von einer abstrakten Klasse können keine Objekte erzeugt werden. Abstrakte Klassen werden benutzt, um eine Ist-eine-Art-von-Beziehung zu modellieren. So lässt sich beispielsweise eine Datenbanktreiber-Hierarchie abbilden, bei der eine gemeinsame Basisklasse die Signaturen für die Methoden der eigentlichen Treiberklassen vorgeben soll. Die Implementierung erfolgt dann gemäß den vorgegebenen Signaturen in den eigentlichen Treiberklassen. Abstrakte Klassen und Methoden werden in PHP mit dem Schlüsselwort abstract deklariert. Wie das aussehen kann, zeigt Beispiel 1.21. In einem UML-Klassendiagramm werden der Name der Klasse sowie die Namen der abstrakten Methoden kursiv geschrieben. Beispiel 1.21: Abstrakte Methoden ImplementierendeKlasse::methode() aufgerufen. Eine Schnittstelle (englisch: interface) ist eine vollständig abstrakte Klasse, die nur Namen und die Signaturen der enthaltenen Methoden vereinbart. Eine Klasse kann eine beliebige Anzahl an Schnittstellen über das Schlüsselwort implements implementieren. Implementiert eine Klasse mehrere Schnittstellen, so entspricht dies einer eingeschränkten Mehrfachvererbung. Da im Gegensatz zur klassenbasierten Mehrfachvererbung, wie sie beispielsweise C++ bietet, keine Funktionalität (sprich: kein Code) vererbt wird, kann es nicht zu den Vererbungseffekten kommen, für die die Mehrfachvererbung berüchtigt ist. Vererbung von Funktionalität kann stattdessen durch Aggregation und Delegation erreicht werden. Mit Hilfe von Schnittstellen können unterschiedliche Rollen eines Objektes bzw. verschiedene Sichten auf ein Objekt modelliert werden. Zusammen mit den Konzepten von Klasse und http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.interfaces.html (1 von 4)07.06.2005 21:48:38
Abstrakte Klassen und Schnittstellen
Vererbung ermöglicht die Verwendung von Schnittstellen die Einordnung von Objekten in unterschiedliche Hierarchien: Abstammung (Klasse und Elternklasse(n)) auf der einen und Fähigkeiten (Schnittstellen) auf der anderen Seite. In einem guten Design wird ein Objekt auf Basis seiner Fähigkeiten (Schnittstellen) verwendet und nicht in Bezug auf seine Herkunft (Klasse, Elternklasse(n)). Die von einem Objekt implementierten Schnittstellen dienen hierbei als Garantie für eine zur Verfügung gestellte Fähigkeit, die für den aktuellen Verwendungskontext des Objektes minimal vorausgesetzt wird. In dem folgenden Beispiel modellieren wir einen "Entsafter" sowie einen "Roller". Der Entsafter soll (über eine Methode entsaften()) Lebensmittel (Gemüse oder Obst) entsaften können, solange diese "entsaftbar" sind. Dieses Merkmal wird in den Lebensmittelklassen dadurch zum Ausdruck gebracht, dass die entsprechende Schnittstelle Entsaftbar implementiert wird. Der Roller soll (über eine Methode rollen() beliebige Objekte rollen können, solange diese "rollbar" sind, und entsprechend die Schnittstelle Rollbar implementieren. Beispiel 1.22: Die Schnittstelle Entsaftbar Beispiel 1.23: Die Schnittstelle Rollbar Die Klasse Tomate (Beispiel 1.24) implementiert beide Schnittstellen, Entsaftbar und Rollbar. Objekte dieser Klasse können daher sowohl mit dem Entsafter (Beispiel 1.26) als auch mit dem Roller (Beispiel 1.27) verwendet werden. Beispiel 1.24: Die Klasse Tomate Beispiel 1.25: Die Klasse Banane
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.interfaces.html (2 von 4)07.06.2005 21:48:38
Abstrakte Klassen und Schnittstellen
Da die Methode entsaften() der Klasse Entsafter (Beispiel 1.26) als Parameter kein Objekt eines bestimmten Typs (beispielweise Lebensmittelgruppen wie Gemüse oder Obst) erwartet, sondern lediglich auf die von ihr benötigte Eigenschaft der "Entsaftbarkeit" testet, kann sie flexibel mit Objekten unterschiedlicher Vererbungshierarchien umgehen, wie Beispiel 1.28 zeigt. Beispiel 1.26: Die Klasse Entsafter Beispiel 1.27: Die Klasse Roller Beispiel 1.28: Entsaftbares entsaften, Rollbares rollen Banane entsaftet: Bananensaft. Tomate entsaftet: Tomatensaft.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.interfaces.html (3 von 4)07.06.2005 21:48:38
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.interfaces.html (4 von 4)07.06.2005 21:48:38
Fehlerbehandlung mit Ausnahmen
Zurück
Fehlerbehandlung mit Ausnahmen Kapitel 1. Grundlagen
Weiter
Fehlerbehandlung mit Ausnahmen Häufig kommt es vor, dass ein Fehler in dem Kontext, in dem er auftritt (beispielsweise in einer Methode), nicht behandelt werden kann. Ein Grund hierfür kann sein, dass die für eine korrekte Behandlung benötigten Informationen nicht verfügbar sind. Vielmehr muss der Fehler an die aufrufende Instanz des Kontextes, in dem er aufgetreten ist, zur Behandlung signalisiert werden. Diese Signalisierung eines Fehlers an den aufrufenden Kontext kann auf zwei Arten erfolgen: "in-band" oder "out-of-band". Bei der "In-band"-Methode wird ein Fehler durch einen ausgezeichneten Wert des Wertebereiches des Rückgabewertes signalisiert. So liefert die getpriority()-Funktion der UNIX-C-Bibliothek beispielsweise einen Wert vom Typ int als Ergebnis. Wie in der UNIX-C-Bibliothek üblich, dient auch hier der Wert -1 als Signal für einen Fehler. Dies führt jedoch zu einem Problem, da -1 ein legitimer Rückgabewert für getpriority() ist. Um unterscheiden zu können, ob eine zurückgegebene -1 einen Fehler signalisiert oder ein normaler Rückgabewert ist, muss der Aufrufer von getpriority() die Variable errno zu Rate ziehen. Abbildung 1.3. Auszug aus der Manual-Page zu getpriority() Since getpriority can legitimately return the value -1, it is necessary to clear the external variable errno prior to the call, then check it afterwards to determine if a -1 is an error or a legitimate value. The setpriority call returns 0 if there is no error, or -1 if there is. Durch die Überprüfung einer zusätzlichen Variablen ist die "In-band"-Methode nicht nur umständlich, sondern auch häufig Grund für Programmierfehler, da keine syntaktische Unterscheidung von http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.exceptions.html (1 von 8)07.06.2005 21:48:39
Fehlerbehandlung mit Ausnahmen
Fehlerzustand und Rückgabewert möglich ist. Ausnahmen, im Englischen Exceptions genannt, sind eine Möglichkeit, Fehlerzustände "out-of-band" zu kommunizieren. Hierbei treten die genannten "In-band"Probleme nicht auf. Code, der für die Behandlung einer Ausnahme typisch ist, wird in so genannten Exception-Klassen gekapselt, die sich in PHP von der Standardklasse Exception ableiten müssen. Abbildung 1.4 zeigt das UML-Klassendiagramm dieser Klasse. Abbildung 1.4. Die Standardklasse Exception
●
getCode() liefert den optionalen numerischen Code der Ausnahme. Dieser Code kann beispielsweise einem Fehlercode entsprechen, wie ihn die PHP-Datenbankschnittstellen im Fehlerfall liefern.
●
getFile() liefert den Namen der Datei, in deren Quelltext die durch das Exception-Objekt repräsentierte Ausnahme ausgelöst wurde.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.exceptions.html (2 von 8)07.06.2005 21:48:39
Fehlerbehandlung mit Ausnahmen ●
getLine() liefert die Nummer der Zeile, in der die durch das Exception-Objekt repräsentierte Ausnahme ausgelöst wurde.
●
getMessage() liefert die optionale Nachricht der Ausnahme. Diese Nachricht kann beispielsweise über den Konstruktor einer Exception-Klasse gesetzt werden.
●
getTrace() liefert die Aufrufliste (englisch: Stack-Trace) bis zur Auslösung der Ausnahme als Array. Dieses hat dieselbe Struktur wie das Ergebnis der PHP-Funktion debug_backtrace().
●
getTraceAsString() liefert die Aufrufliste als String.
Die Methoden der Klasse Exception sind final und können daher in einer Kindklasse nicht redefiniert werden. Eine Ausnahme (ein Objekt einer von Exception abgeleiteten Klasse) wird mit dem throw-Operator "geworfen". Die Ausführung des aktuellen Programmkontextes wird hierdurch abgebrochen und die Ausnahme wird an den aufrufenden Kontext zurückgegeben. Wie in C# so wird auch in PHP (im Gegensatz zu beispielsweise Java) in der Signatur einer Methode nicht deklariert, welche Ausnahmen in ihrem Rumpf ausgelöst werden können. Ausnahmen sind in PHP "unchecked", was die Erweiterung und Vererbung von Klassen erleichtert. Eine interessante Diskussion zu diesem Thema mit Anders Hejlsberg, dem Lead-Designer der Programmiersprache C#, gibt es in [TheTroublewithCheckedExceptions]. Beispiel 1.29 zeigt die Klasse DB_Exception, die wir im Folgenden in unserer Datenbankklasse einsetzen möchten. Diese Klasse definiert keine eigene Funktionalität. Sie wird nur eingeführt, damit bei der Ausnahmenbehandlung anhand des Exception-Typs zwischen Datenbankfehlern (repräsentiert durch DB_Exception) und allgemeinen Fehlern (Exception) unterschieden werden kann. Beispiel 1.29: Die Klasse DB_Exception http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.exceptions.html (3 von 8)07.06.2005 21:48:39
Fehlerbehandlung mit Ausnahmen
Beispiel 1.30 zeigt, wie in den Methoden connect() und query() mit dem throw-Operator bei Auftreten eines Fehlers eine Ausnahme, in diesem Fall vom Typ DB_Exception, ausgelöst wird. Beispiel 1.30: Fehlerbehandlung mit Ausnahmen Ein Codeblock, in dem Ausnahmen ausgelöst werden können, wird mit dem try-Schlüsselwort ausgezeichnet und mit geschweiften Klammern umschlossen. Direkt nach diesem Block steht eine beliebige Anzahl von catch-Blöcken, für jede mögliche Ausnahme ein Block. Ein solcher Block beginnt mit dem catch-Schüsselwort, danach folgen in runden Klammern der Name der erwarteten Exception-Klasse und der Name einer Variablen, in der das entsprechende Objekt im catch-Block bereitgestellt werden soll. Der eigentliche catch-Block folgt direkt im Anschluss und ist analog zum try-Block mit geschweiften Klammern umschlossen. Beispiel 1.31 zeigt die Verwendung von try und catch. Beispiel 1.31: Verwendung der um Ausnahmebehandlung erweiterten Klasse In anderen Programmiersprachen, die Ausnahmebehandlung anbieten (beispielsweise Java), kann nach einem catch-Block optional noch ein finally-Block folgen. Ein solcher Block wird auf jeden Fall ausgeführt. Eine typische Anwendung ist die Freigabe von Ressourcen oder das Schließen von Dateien. PHP bietet diesen Mechanismus in Version 5.0 noch nicht an, dieser kann jedoch nachgebildet werden (siehe Beispiel 1.32). Beispiel 1.32: Nachbildung von finally in PHP Eine unbehandelte Ausnahme führt zum Abbruch der Programmausführung. Hierbei wird ein so genannter Stack-Trace ausgegeben, der bei der Suche nach der Ursache der Ausnahme helfen soll. Beispiel 1.33: Eine unbehandelte Ausnahme führt zum Abbruch der Programmausführung Fatal error: Uncaught exception 'Exception' with message 'Test' in /home/sb/ uncaught_exception.php:2 Stack trace: #0 {main} thrown in /home/sb/uncaught_exception.php on line 2 Für die Verarbeitung von unbehandelten Ausnahmen kann eine PHP-Funktion mit der Funktion set_exception_handler() registriert werden. Auf diesem Weg kann die Ausnahme beispielsweise in einem Logfile protokolliert oder die Ausgabe der Fehlermeldung angepasst werden. http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.exceptions.html (7 von 8)07.06.2005 21:48:39
Fehlerbehandlung mit Ausnahmen
Beispiel 1.34: Anpassen der Verarbeitung von unbehandelten Ausnahmen Zurück Abstrakte Klassen und Schnittstellen
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.exceptions.html (8 von 8)07.06.2005 21:48:39
Weiter Serialisierung von Objekten
Serialisierung von Objekten
Zurück
Serialisierung von Objekten Kapitel 1. Grundlagen
Weiter
Serialisierung von Objekten Objekte existieren nur zur Laufzeit, können aber durch die Speicherung ihres Zustandes persistent (dauerhaft) gemacht werden. Sie können somit gespeichert und zu einem späteren Zeitpunkt wieder geladen werden. Die Speicherung eines Objektes und seines Zustands wird auch Serialisierung genannt. PHP bietet die Funktionen serialize() und unserialize(), um ein Objekt zu serialisieren beziehungsweise aus der serialisierten Form wieder ein Objekt zu erstellen. Hierbei erzeugt serialize() aus einem Objekt einen String, in dem die relevanten Daten kodiert sind. Dieser String kann dann beispielsweise in eine Datei geschrieben oder in einer Datenbank abgelegt werden. Analog erwartet unserialize() einen String in diesem Format, um ein Objekt aus dem kodierten String wiederherzustellen. Verfügt die Klasse des Objektes, das serialisiert werden soll, über eine __sleep-Methode, so wird diese automatisch vor der eigentlichen Serialisierung auf dem Objekt aufgerufen. Diese Methode muss ein Array mit den Namen derjenigen Instanzvariablen zurückliefern, die serialisiert werden sollen. So kann die __sleep-Methode einer Klasse, die eine Datenbankverbindung kapselt, beispielsweise Sorge dafür tragen, dass nur die für den Verbindungsaufbau nötigen Parameter gespeichert werden, nicht aber die Ressource-ID der aktuell bestehenden Verbindung. Verfügt die Klasse des Objektes, das deserialisiert werden soll, über eine __wakeupMethode, so wird diese automatisch nach der eigentlichen Deserialisierung auf dem Objekt aufgerufen. Wird ein Objekt durch Ablegen in dem Array $_SESSION[] als Session-Variable registriert, so kümmert sich PHP automatisch um Serialisierung und Deserialisierung des Objektes zwischen den einzelnen Requests der Session. Beispiel 1.35: Verwendung der Methoden __sleep() und __wakeup() __sleep() aufgerufen. http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.serialization.html (1 von 2)07.06.2005 21:48:40
Serialisierung von Objekten
__wakeup() aufgerufen. In Kapitel 12 werden wir mit Propel eine Lösung kennen lernen, die das Speichern von Objekten in einer relationalen Datenbank ermöglicht. Zurück Fehlerbehandlung mit Ausnahmen
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.serialization.html (2 von 2)07.06.2005 21:48:40
Weiter Die Reflection API
Die Reflection API
Zurück
Die Reflection API Kapitel 1. Grundlagen
Weiter
Die Reflection API Die strukturelle Reflexion, auch Introspektion genannt, macht die Struktur eines objektorientierten Systems durch die Programmiersprache des Systems zugänglich. Dies ermöglicht das Schreiben von generischem Code, der zur Laufzeit Informationen über Klassen und deren Objekte abfragt und diese entsprechend verarbeitet. Diese Generizität wird beispielsweise für das Schreiben von Code- und Dokumentationsgeneratoren benötigt. Ferner bildet sie die Grundlage für Werkzeuge wie PHPUnit (Kapitel 4), die "fremden" Code analysieren und ausführen müssen. Für den "Blick in das Innere" von Klassen und Objekten bietet PHP die so genannte Reflection API an, die die folgenden Klassen und Schnittstellen umfasst: ●
Reflector ist die Schnittstelle, die von allen Klassen der Reflection API implementiert wird.
●
Reflection ist eine statische Hilfsklasse, die die Arbeit mit ReflectorObjekten erleichtert.
●
ReflectionException ist die von Exception abgeleitete AusnahmeKlasse, die für das Signalisieren von Fehlern innerhalb der Reflection API verwendet wird.
●
ReflectionExtension repräsentiert die Informationen über eine PHPErweiterung.
●
ReflectionFunction repräsentiert die Informationen über eine Funktion.
●
ReflectionParameter repräsentiert die Informationen über einen Parameter einer Funktion oder Methode.
●
ReflectionClass repräsentiert die Informationen über eine Klasse.
●
ReflectionObject ist eine Erweiterung von ReflectionClass und repräsentiert die Informationen über ein Objekt.
●
ReflectionMethod ist eine Erweiterung von ReflectionFunction und repräsentiert die Informationen über eine Methode.
●
ReflectionProperty repräsentiert die Informationen über eine Instanzvariable einer Klasse oder eines Objektes.
Allen Klassen der Reflection API gemein ist die statische Methode export(). http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.reflection-api.html (1 von 4)07.06.2005 21:48:41
Die Reflection API
Diese liefert eine textuelle Darstellung des reflektierten Sprachobjekts. Beispiel 1.36 zeigt ein entsprechendes Beispiel. Beispiel 1.36: Verwendung von ReflectionClass::export() Class [ class Klasse ] { @@ /home/sb/export.php 2-11 - Constants [0] { } - Static properties [0] { } - Static methods [0] { } - Properties Property [ Property [ Property [ }
- Methods [1] { Method [ public method methode ] { @@ /home/sb/export.php 7 - 10 - Parameters [1] { Parameter #0 [ Klasse $objekt ] } } } } Stellvertretend für die Klassen der Reflection API betrachten wir die Klasse ReflectionClass. Diese bietet die folgenden Methoden: ●
getFileName(), getStartLine(), getEndLine(), getDocComment(), getExtension() und getExtensionName() liefern Informationen über die Deklaration der Klasse in einer Quelltextdatei beziehungsweise in
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.reflection-api.html (2 von 4)07.06.2005 21:48:41
Die Reflection API
●
einer PHP-Erweiterung. isInternal(), isUserDefined(), isInstantiable(), isInterface(), isAbstract(), isFinal(), getParentClass(), isSubclassOf(), implementsInterface() und isIterateable() liefern Informationen über Eigenschaften der Klasse wie beispielsweise Vererbungsbeziehungen.
●
getMethod(), getMethods(), getProperty(), getProperties(), getConstants() und getConstant() liefern beispielsweise Objekte der Klassen ReflectionMethod und ReflectionProperty, um mit den Methoden, Instanzvariablen und Konstanten einer Klasse zu arbeiten.
In Beispiel 1.37 erzeugen wir zunächst ein Objekt der Klasse ReflectionClass für die Klasse Test aus Beispiel 1.36. Über die Methode getMethod() dieses Objektes gelangen wir an ein Objekt der Klasse ReflectionMethod, das die Methode Test::aPublicMethod repräsentiert. Diese Methode können wir mit ReflectionMethod::invoke() ausführen. Als ersten Parameter müssen wir das Objekt der zugehörigen Klasse (in unserem Beispiel Test) übergeben, auf dem die Methode ausgeführt werden soll. Danach folgen die Parameter der Methode, die aufgerufen werden soll.
[5]
[6]
Beispiel 1.37: ReflectionClass und ReflectionMethod im Einsatz Klasse
[5]
Handelt es sich bei der Methode, die über ReflectionMethod::invoke()
aufgerufen werden soll, um eine Klassenmethode, so ist NULL anstelle eines Objektes zu übergeben. [6]
In PHP 5.1 wird es eine neue Methode invokeArgs() geben, der man die
Parameter der aufzurufenden Methode nicht einzeln, sondern als Array
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.reflection-api.html (3 von 4)07.06.2005 21:48:41
Die Reflection API
übergeben kann. Zurück Serialisierung von Objekten
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.reflection-api.html (4 von 4)07.06.2005 21:48:41
Migration von PHP 4 zu PHP 5
Zurück
Migration von PHP 4 zu PHP 5 Kapitel 1. Grundlagen
Weiter
Migration von PHP 4 zu PHP 5 Bei der Entwicklung von PHP 5 wurde versucht, die Abwärtskompatibilität zu PHP 4 zu wahren. In diesem Abschnitt finden Sie eine Übersicht über Änderungen in PHP 5, die eine Änderung von bestehenden PHP-4-Anwendungen erforderlich macht. ●
Kopie versus Referenz Mit der Einführung des neuen Objektmodells werden Objekte standardmäßig per Referenz übergeben. In PHP 4 wurde stattdessen stets eine Kopie übergeben. Für PHPProgramme, die wie von PHP 4 gewohnt eine Kopie statt einer Referenz erwarten, kann die php.ini-Direktive zend. ze2_compatibility_mode auf On gesetzt werden.
●
Konstruktor In PHP 4 entsprach der Name des Konstruktors dem Namen der Klasse. In PHP 5 heißt der Konstruktor nun __construct. Wird in einer Klasse keine Methode mit dem Namen __construct deklariert, so wird nach einer Methode gesucht, die den Namen der Klasse trägt. Wird eine solche Methode gefunden, so wird sie als Konstruktor benutzt. Wird eine Methode mit dem Namen __construct gefunden, so wird diese in jedem Fall (unabhängig davon, ob auch eine Methode mit dem Namen der Klasse existiert) benutzt.
●
Klassendeklaration vor Objekterzeugung In PHP 4 war es möglich, ein Objekt einer Klasse zu erzeugen, die zum Zeitpunkt der Instanzierung noch nicht deklariert war. In PHP 5 ist dies nicht mehr möglich, wenn die Klasse Sprachmerkmale verwendet, die mit PHP 5
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.migration.html (1 von 3)07.06.2005 21:48:41
Migration von PHP 4 zu PHP 5
eingeführt wurden. Klassen, die nur Sprachmerkmale enthalten, die bereits in PHP 4 zur Verfügung standen, können weiterhin vor ihrer Deklarierung verwendet werden. ●
Neue Schlüsselwörter In PHP 5 sind eine Reihe von neuen Schlüsselwörtern hinzugekommen, die nicht mehr als Namen von Klassen, Konstanten, Methoden oder Funktionen verwendet werden können: ❍ abstract ❍ catch ❍ clone ❍ final ❍ implements ❍ interface ❍ private ❍ protected ❍ public ❍ throw ❍ try Bei der Migration von PHP 4 nach PHP 5 müssen Klassen, Konstanten, Methoden oder Funktionen, die einen dieser Namen tragen, umbenannt werden.
●
Besondere Methoden In PHP 5 sind einige Methodennamen hinzugekommen, die mit einer besonderen Semantik verknüpft sind: ❍ __autoload ❍ __call ❍ __clone ❍ __construct ❍ __destruct ❍ __get
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.migration.html (2 von 3)07.06.2005 21:48:41
Migration von PHP 4 zu PHP 5 ❍ ❍
__set __toString
Bei der Migration von PHP 4 nach PHP 5 müssen Methoden, die einen dieser Namen tragen, umbenannt werden. Zurück Die Reflection API
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.foundations.migration.html (3 von 3)07.06.2005 21:48:41
__autoload
Zurück
__autoload Kapitel 2. Interzeptormethoden
Weiter
__autoload Die Funktion __autoload($className) wird außerhalb einer Klasse (im globalen Sichtbarkeitsbereich) deklariert. Der PHP-Interpreter ruft diese Funktion automatisch auf, wenn ein Objekt einer nicht deklarierten Klasse erzeugt werden soll. Der Name der Klasse wird hierbei als Parameter an die Funktion übergeben. In der Funktion __autoload() kann so an zentraler Stelle ein Mechanismus implementiert werden, der die entsprechende Quelltextdatei für eine Klasse lädt. In Projekten mit einer komplexen Klassenhierarchie hilft ein solcher Mechanismus das Problem zu verhindern, dass nur die für die aktuelle Ausführung benötigten Klassen geladen werden und nicht sämtliche Klassen der Anwendung. Ohne einen solchen Mechanismus, der selektiv die benötigten Quelltextdateien lädt, wäre in einem solchen Fall der Aufwand für das Laden und Kompilieren aller Klassen größer als der Aufwand für die eigentliche Ausführung der Methoden der tatsächlich benötigten Klassen. Beispiel 2.1 zeigt eine Implementierung der Funktion __autoload(), die über ein assoziatives Array die Auflösung von Klassennamen zu entsprechender Quelltextdatei vornimmt, und diese dann lädt. Beispiel 2.1: Verwendung der __autoload-Funktion Zurück
Nach oben
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.interceptors.autoload.html (1 von 2)07.06.2005 21:48:42
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.interceptors.autoload.html (2 von 2)07.06.2005 21:48:42
__get
__get
Zurück
__get Kapitel 2. Interzeptormethoden
Weiter
__get Aggregiert ein Objekt ein anderes, so wird das aggregierte Objekt häufig im Konstruktor erzeugt und in der entsprechenden Instanzvariablen abgelegt (Beispiel 2.2). Auf diese Weise steht das aggregierte Objekt für den gesamten Lebenszyklus des aggregierenden Objektes zur Verfügung und kann beispielsweise von dessen Methoden genutzt werden. Beispiel 2.2: Die Klasse ExpensiveInitialization Für den Fall, dass die Methoden des aggregierenden Objektes eher selten auf das aggregierte Objekt für die Ausführung ihrer Aufgaben zugreifen müssen, kann das oben beschriebene Verfahren eher ungeeignet sein. Ist die Erzeugung des aggregierten Objektes teuer, was beispielsweise bei der Kapselung von Ressourcen wie Datenbankverbindungen durch das aggregierte Objekt der Fall ist, ist es sinnvoll, das aggregierte Objekt erst bei seiner ersten Verwendung zu erzeugen. Dieses Konzept wird Lazy Initialization genannt und kann beispielsweise mit der Interzeptormethode __get($memberName) (Beispiel 2.3) implementiert werden. Beispiel 2.3: Die Klasse LazyInitialization Zurück __autoload
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.interceptors.get.html (2 von 2)07.06.2005 21:48:42
__set
Zurück
__set Kapitel 2. Interzeptormethoden
Weiter
__set PHP erlaubt die spontane Erzeugung von Instanzvariablen in einem Objekt zur Laufzeit, ohne dass diese vorher deklariert werden müssen. Diese Instanzvariablen sind implizit public. Mit Hilfe der Methoden __get ($memberName) und __set($memberName, $value) kann dieses Verhalten angepasst und so genannte virtuelle Instanzvariablen realisiert werden. Die Klasse VirtualMembers aus Beispiel 2.4 setzt das Standardverhalten beim Zugriff auf nicht deklarierte Instanzvariablen für ihre Objekte außer Kraft. Sie speichert den Inhalt dieser Variablen in einem Array, das in einer als private deklarierten Instanzvariablen liegt. Beispiel 2.4: Implementierung von virtuellen Instanzvariablen Beispiel 2.5 zeigt mit der Klasse Person einen möglichen Verwendungszweck für virtuelle Instanzvariablen. Die Klasse Person kapselt Personeninformationen, die in einer Tabelle personen in einer Datenbank abgelegt sind. Eine Zeile dieser Tabelle entspricht einer Person, die Spalte id identifiziert jede Person eindeutig (Primärschlüssel). Durch Verwendung von virtuellen Instanzvariablen erlaubt diese Klasse transparenten Schreib-/ Lesezugriff auf die Personentabelle über ein Personenobjekt. Beispiel 2.5: Virtuelle Instanzvariablen im Einsatz Sebastian Bergmann Professionelle Softwareentwicklung mit PHP 5 3-89864-229-1 http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.simplexml.html (2 von 8)07.06.2005 21:49:05
SimpleXML
Hakan Kücükyilmaz Thomas M. Haas Alexander Merz PHP 5 3-89864-236-4
Abbildung 8.2. Repräsentation der XML-Daten in einem SimpleXMLElement-Objekt SimpleXMLElement Object ( [book] => Array ( [0] => SimpleXMLElement Object ( [author] => Sebastian Bergmann [title] => Professionelle Softwareentwicklung mit PHP 5 [isbn] => 3-89864-229-1 ) [1] => SimpleXMLElement Object ( [author] => Array ( [0] => Hakan Kücükyilmaz [1] => Thomas M. Haas [2] => Alexander Merz ) [title] => PHP 5 [isbn] => 3-89864-236-4 ) ) ) http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.simplexml.html (3 von 8)07.06.2005 21:49:05
SimpleXML
Da ein SimpleXMLElement-Objekt über eine Implementierung des __toString()-Interzeptors (siehe „__toString“) verfügt, kann auf den Inhalt (CDATA) eines XML-Elementes wie auf einen String zugegriffen werden, beispielsweise über print. Beispiel 8.2 zeigt den Zugriff auf den Inhalt des title-Elementes des ersten book-Elementes. Beispiel 8.2: Zugriff auf ein XML-Element mit SimpleXML Professionelle Softwareentwicklung mit PHP 5 Die Methode attributes() eines SimpleXMLElement-Objektes liefert ein assoziatives Array mit den Attributen eines XML-Elementes. Beispiel 8.3: Zugriff auf ein XML-Attribut mit SimpleXML lang: de Die Klasse SimpleXMLElement implementiert die Iterator-Schnittstelle Traversable (siehe Kapitel 3). Ein SimpleXMLElement-Objekt kann daher mit dem foreach-Operator iteriert (und damit die darin gekapselten XML-Daten verarbeitet) werden, wie Beispiel 8.4 zeigt. http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.simplexml.html (4 von 8)07.06.2005 21:49:05
SimpleXML
Beispiel 8.4: Zugriff auf den Buchkatalog mit SimpleXML und foreach() Sebastian Bergmann: "Professionelle Softwareentwicklung mit PHP 5" ISBN: 3-89864-229-1 Hakan Kücükyilmaz, Thomas M. Haas, Alexander Merz: "PHP 5" ISBN: 3-89864-236-4 Der Inhalt von SimpleXMLElement-Objekten kann durch Zugriff auf die entsprechenden Instanzvariablen geändert werden, wie Beispiel 8.5 zeigt. Beispiel 8.5: Ein SimpleXMLElement-Objekt ändern und als XML ausgeben http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.simplexml.html (5 von 8)07.06.2005 21:49:05
SimpleXML
Johannes Sebastian Bergmann Professionelle Softwareentwicklung mit PHP 5 3-89864-229-1 Über die Methode xpath() eines SimpleXMLElement-Objektes können Anfragen in der XML Path Language (XPath) gestellt werden. Beispiel 8.6 zeigt eine Anfrage, die die Titel der im Katalog enthaltenen Bücher liefert. Das Ergebnis einer solchen Anfrage ist ein Array von SimpleXMLElement-Objekten. Beispiel 8.6: Verwenden von XPath mit SimpleXML Professionelle Softwareentwicklung mit PHP 5 PHP 5
Die Klasse SimpleXMLIterator Mit der Klasse SimpleXMLIterator bietet die Standard PHP Library (siehe Kapitel 3) eine Alternative zu SimpleXMLElement an, um die Elemente eines XML-Dokumentes für die Verarbeitung mit SimpleXML zu kapseln. SimpleXMLIterator bietet die Schnittstelle RecursiveIterator an, und kann daher mit einem RecursiveIteratorIterator rekursiv alle Elemente eines XML-Dokumentes aufzählen. In Beispiel 8.7 rufen wir die Funktion simplexml_load_file() mit ihrem optionalen zweiten Parameter auf, um einen SimpleXMLIterator anstelle eines SimpleXMLElement-Objektes zu erhalten. Im Anschluss http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.simplexml.html (6 von 8)07.06.2005 21:49:05
SimpleXML
erzeugen wir einen RecursiveIteratorIterator für den SimpleXMLIterator. Dieser zählt alle XMLElemente einschließlich der Wurzel (RIT_SELF_FIRST) auf. Beispiel 8.7: Rekursives Aufzählen der Elemente eines XML-Dokumentes book author title isbn book author author author title isbn Innerhalb der foreach-Schleife aus Beispiel 8.7 enthält die Variable $name den Namen des aktuellen XMLElementes und $element das entsprechende Objekt.
Vor- und Nachteile ●
+ Einfacher Zugriff auf XML-Element.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.simplexml.html (7 von 8)07.06.2005 21:49:05
SimpleXML
[9]
●
+ Geringer Speicherverbrauch, da PHP-Objekte nur bei Bedarf erzeugt werden und das Dokument zu
●
Beginn nur einmal (im Speicher der libxml2-Bibliothek) vorliegt. + Schnell.
●
- Zugriff auf Attribute eines XML-Elementes umständlich.
●
- Kein Standard.
Die PHP-Array-Funktionen können auf ein solches Array nicht angewendet werden. is_array($books-
>book[1]->author) liefert in unserem Beispiel FALSE als Ergebnis. Die PHP-Debug-Funktionen print_r() und var_dump() zeigen allerdings $books->book[1]->author als Array. Zurück Kapitel 8. XML-Verarbeitung mit PHP
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.simplexml.html (8 von 8)07.06.2005 21:49:05
Weiter Simple API for XML (SAX)
Simple API for XML (SAX)
Zurück
Simple API for XML (SAX) Kapitel 8. XML-Verarbeitung mit PHP
Weiter
Simple API for XML (SAX) Bei der Verarbeitung von XML-Daten mit der Simple API for XML (SAX) ruft der XML-Parser für bestimmte Ereignisse (öffnendes Element-Tag, ...) vom Programmierer zuvor bestimmte Funktionen oder Methoden auf. Die XML-Daten werden so ereignisorientiert verarbeitet. Wir betrachten zunächst die drei Ereignisse, die bei der Verarbeitung von XMLDaten am wichtigsten sind: "Start Element", "End Element" und "Character Data". ●
xml_set_element_handler($parser, , ) registriert die Callbacks für die Ereignisse "Start Element" und "End Element". Die Funktion oder Methode, die für das Ereignis "Start Element" aufgerufen werden soll, muss drei Parameter $parser, $name und $attributes akzeptieren. Letzterer enthält ein assoziatives Array der Attribute des XMLElementes. Die Funktion oder Methode, die für das Ereignis "End Element" aufgerufen werden soll, muss zwei Parameter $parser und $name akzeptieren.
●
xml_set_character_data_handler($parser, ) registriert den Callback für das Ereignis "Character Data". Die Funktion oder Methode, die für das Ereignis "Character Data" aufgerufen werden soll, muss zwei Parameter $parser und $cdata akzeptieren.
Bei der Registrierung eines Callbacks kann als der Name einer Funktion oder ein Array, das eine Referenz auf ein Objekt sowie den Namen der für das Ereignis aufzurufenden Methode des Objektes enthält, angegeben werden. Beispiel 8.8 zeigt die Verarbeitung des Buchkatalogs (Beispiel 8.1). Beispiel 8.8: Zugriff auf den Buchkatalog mit SAX Sebastian Bergmann http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.sax.html (2 von 3)07.06.2005 21:49:06
Simple API for XML (SAX)
Professionelle Softwareentwicklung mit PHP 5 ISBN: 3-89864-229-1 Hakan Kücükyilmaz, Thomas M. Haas, Alexander Merz PHP 5 ISBN: 3-89864-236-4 Da der SAX-Parser die XML-Daten linear verarbeitet und stets nur die Daten im Speicher hält, die zu dem aktuellen Ereignis gehören, muss der Programmierer Buch über Daten wie das aktuelle Element führen. In unserem Beispiel legen wir hierzu den Namen des Elementes bei einem öffnenden XML-Tag auf einen Stapel. Im Callback für Character Data können wir so nachvollziehen, zu welchem Element die aktuellen Daten gehören. Erreicht der Parser das schließende XMLTag, so entfernen wir den Namen des Elements wieder von dem Stapel. Die Simple API for XML bietet über die Behandlung der Ereignisse "Start Element", "End Element" und "Character Data" hinaus die folgenden Callbacks an: ●
xml_set_processing_instruction_handler($parser, ) registriert den Callback für das Ereignis "Processing Instruction".
●
xml_set_external_entity_ref_handler($parser, ) registriert den Callback für das Ereignis "External Entity Reference".
●
xml_set_notation_decl_handler($parser, ) registriert den Callback für das Ereignis "Notation Declaration".
●
xml_set_unparsed_entity_decl_handler($parser, ) registriert den Callback für das Ereignis "Unparsed Entity Declaration".
●
xml_set_default_handler($parser, ) registriert einen Callback, der für all jene Ereignisse aufgerufen wird, für die kein eigener Callback registriert wurde.
Vor- und Nachteile ● ●
● ● ● ●
+ Standard, wenn auch nicht vom World Wide Web Consortium. + Geringer Speicherverbrauch, da immer nur das aktuelle XML-Element verfügbar ist. + Schnell. - Lineare Verabeitung, kein beliebiger Zugriff auf Elemente möglich. - Kein Schreibzugriff möglich. - Programmierer muss sich um Buchhaltung kümmern.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.sax.html (3 von 3)07.06.2005 21:49:06
Document Object Model (DOM)
Zurück
Document Object Model (DOM) Kapitel 8. XML-Verarbeitung mit PHP
Weiter
Document Object Model (DOM) Mit dem Document Object Model (DOM) bietet das World Wide Web Consortium (W3C) einen mächtigen Standard an, der eine plattform- und sprachunabhängige neutrale Programmierschnittstelle für den lesenden und schreibenden Zugriff auf gültige HTML und wohlgeformte XML-Dokumente definiert. PHP 5 bietet mit seiner DOM-Erweiterung, die nicht abwärtskompatibel zur DOM-XML-Erweiterung von PHP 4 ist, eine vollständige Implementierung der "Level 2 Core"-Version des DOM-Standards. Teilweise werden auch Bestandteile ("Load and Save") der neueren Version "Level 3" umgesetzt. Das Document Object Model fasst jeden Bestandteil eines XML-Dokumentes als einen Knoten auf. Das Dokument selbst (DOMDocument), seine Elemente (DOMElement) sowie deren Attribute (DOMAttr) und textuelle Inhalte (DOMText) werden durch Objekte entsprechender Knotenklassen repräsentiert, die untereinander mit Referenzen verknüpft sind. Abbildung 8.3 zeigt den DOM-Objektbaum für das XML-Dokument aus Beispiel 8.1. Abbildung 8.3. DOM-Repräsentation des Buchkatalogs
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.dom.html (1 von 11)07.06.2005 21:49:09
Document Object Model (DOM)
Die DOM-Implementierung von PHP 5 umfasst 29 Klassen mit insgesamt 360 Methoden. Wir konzentrieren uns an dieser Stelle auf die wichtigsten (Tabelle 8.1). Tabelle 8.1. Die wichtigsten Klassen des Document Object Model Klasse
Elternklasse oder Schnittstelle Aufgabe Basisklasse der verschiedenen Knotenklassen eines DOM-Baumes.
DOMNode DOMDocument
DOMNode
Bildet den Einstiegspunkt des DOM-Baumes.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.dom.html (2 von 11)07.06.2005 21:49:09
Document Object Model (DOM)
DOMElement
DOMNode
Repräsentiert ein XML-Element und bietet Methoden für den Zugriff auf XML-Elemente.
DOMAttr
DOMNode
Repräsentiert ein Attribut eines XML-Elementes.
DOMCharacterData DOMNode
Repräsentiert den Character-Data-Teil eines XML-Elementes.
DOMText
DOMCharacterData
Repräsentiert textuelle Inhalte eines XML-Dokuments.
DOMNodeList
Traversable
Repräsentiert eine Menge von Knoten. Ermöglicht das Formulieren von XPath-Anfragen.
DOMXPath DOMException
Exception
Ausnahmeklasse.
Laden und Speichern von XML-Dokumenten Die Methode DOMDocument::load($filename), die sowohl auf einem Objekt als auch statisch aufgerufen werden kann, lädt ein XML-Dokument aus einer Datei. Wird die Methode statisch aufgerufen, so liefert sie ein Objekt der Klasse DOMDocument als Ergebnis (siehe beispielsweise Beispiel 8.12). DOMDocument::loadXML($xml) lädt ein XML-Dokument aus einem String, die Funktion dom_import_simplexml($sxe) erzeugt ein Objekt der Klasse DOMDocument aus einem Objekt der Klasse SimpleXMLElement. Analog laden die Methoden DOMDocument::loadHTMLFile($filename) und DOMDocument::loadHTML($html) ein HTMLDokument aus einer Datei oder aus einem String. Die Methoden DOMDocument::save($filename) und DOMDocument::saveXML() speichern ein DOMDocument-Objekt als XMLDaten in eine Datei oder einen String. Für HTML-Dokumente gibt es entsprechend die Methoden DOMDocument:: saveHTMLFile($filename) und DOMDocument::saveHTML(). Die genannten Methoden nutzen das Streams-System von PHP 5 und können daher, je nachdem welche StreamUnterstützungen in PHP einkompiliert wurden, beispielsweise eine XML-Datei von einem entfernten HTTP-Server öffnen oder auf einem FTP-Server speichern. An Stelle eines Dateinamens ist hierbei die entsprechende URL als $filename anzugeben.
Erzeugen eines neuen XML-Dokumentes http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.dom.html (3 von 11)07.06.2005 21:49:09
Document Object Model (DOM)
In Beispiel 8.9 erzeugen wir zunächst ein Objekt der Klasse DOMDocument. Dem Konstruktor übergeben wir die gewünschte Version des XML-Standards ('1.0') und die zu verwendende Zeichenkodierung ('iso-8859-1'). Die Methode DOMDocument::createElement() erzeugt ein neues Objekt der Klasse DOMElement. Über die Methode DOMNode::appendChild() wird dieses dann an der gewünschten Stelle in den DOM-Baum "eingehängt". Beispiel 8.9: Erzeugen eines neuen XML-Dokumentes http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.dom.html (4 von 11)07.06.2005 21:49:09
Document Object Model (DOM)
Sebastian Bergmann Professionelle Softwareentwicklung mit PHP 5 3-89864-229-1 Erzeugen eines neuen XML-Dokumentes durch direkte Verwendung der DOM-Klassen, wie es in Beispiel 8.9 gezeigt ist, kann recht aufwändig werden. In solchen Fällen bietet es sich an, die DOM-Klassen durch Vererbung zu erweitern und für den konkreten Verwendungszweck anzupassen. Die Klasse Book (Beispiel 8.10) erweitert die Klasse DOMElement um die für das -Element spezifischen Methoden setAuthor($author), setISBN($isbn), setLanguage($language) und setTitle($title). So wird dem Verwender der Klasse das Aufrufen von DOMDocument::createElement() und DOMNode::appendChild() abgenommen. Beispiel 8.10: Die Klasse Book Die Klasse Books (Beispiel 8.11) erweitert die Klasse DOMDocument und bietet mit ihrer Methode createBook() eine einfache Möglichkeit, ein neues -Element zu erzeugen. Beispiel 8.11: Die Klasse Books Beispiel 8.11 erzeugt dieselbe Ausgabe wie Beispiel 8.9.
Verwenden der DOMNodeList-Klasse Die Klasse DOMNodeList repräsentiert eine Menge von Knoten, also Objekten der Klasse DOMNode. Es wird keine spezielle Ordnung für die Knoten vorgegeben. DOMNodeList implementiert die Schnittstelle Traversable (siehe Kapitel 3), entsprechende Objekte können daher mit dem foreach-Operator iteriert werden. Beispiel 8.12 benutzt die Methode DOMDocument::getElementsByTagName(), um alle -Elemente zu erhalten. Als Ergebnis liefert die Methode ein Objekt der Klasse DOMNodeList, das die entsprechenden DOMElement-Objekte enthält. $author->nodeValue greift auf den Wert des DOMText-Knotens zu, der an dem von $author referenzierten DOMElementObjekt hängt. Beispiel 8.12: Verwenden der DOMNodeList-Klasse Sebastian Bergmann Hakan Kücükyilmaz Thomas M. Haas Alexander Merz
Formulieren von XPath-Anfragen Über die Klasse DOMXPath können XPath-Anfragen an einen DOM-Baum gestellt werden. Das Ergebnis ist wieder ein Objekt der Klasse DOMNodeList. http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.dom.html (7 von 11)07.06.2005 21:49:09
Document Object Model (DOM)
Beispiel 8.13: Formulieren von XPath-Anfragen Professionelle Softwareentwicklung mit PHP 5 PHP 5
Validieren von XML-Dokumenten Neben der Verarbeitung von XML-Dokumenten ermöglicht die PHP-DOM-Erweiterung auch die Validierung von XMLDokumenten gegen Spezifikationen in den Formaten Document Type Definition (DTD), XML Schema (XSD) und RelaxNG (RNG). XML Schema ist die offizielle Nachfolgetechnologie des W3C für die Document Type Definition. Ein Schemas wird benutzt, um eine Klasse von XML-Dokumenten zu definieren. Anhand eines Schemas kann für ein konkretes XML-Dokument überprüft werden, ob es die Schema-Definition erfüllt. Man sagt, ein XML-Dokument validiert gegen ein XML Schema. Beispiel 8.14 zeigt die Verwendung der von PHP 5 zur Verfügung gestellten Methode DOMDocument::schemaValidate(). Beispiel 8.14: XML-Schema-Validierung books.xml entspricht der XML-Schema-Deklaration in books.xsd.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.dom.html (8 von 11)07.06.2005 21:49:09
Document Object Model (DOM)
Beispiel 8.15: XML-Schema-Deklaration für den Buchkatalog
RelaxNG ist eine parallel zu XML Schema entstandene Schema-Sprache für die Definition von XML-Dokumenten, die derzeit ISO-standardisiert wird. Sie wird nicht vom W3C unterstützt, nutzt aber die von XML Schema definierten Datentypen. RelaxNG tritt an, eine leichter erlernbarere Alternative zu XML Schema zu sein. Beispiel 8.14 zeigt die Verwendung der Methode DOMDocument::relaxngValidate(). Beispiel 8.16: RelaxNG-Validierung books.xml entspricht der RelaxNG-Deklaration in books.rng. Beispiel 8.17: RelaxNG-Deklaration für den Buchkatalog
Vor- und Nachteile http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.dom.html (10 von 11)07.06.2005 21:49:09
Document Object Model (DOM)
● ● ●
+ Implementierung eines mächtigen Standards. + Lese- und Schreibzugriff auf beliebige XML-Elemente möglich. - Langsam und speicherintensiv, da ein vollständiger Baum von PHP-Objekten erzeugt werden muss.
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.dom.html (11 von 11)07.06.2005 21:49:09
Weiter XSL Transformations (XSLT)
XSL Transformations (XSLT)
Zurück
XSL Transformations (XSLT) Kapitel 8. XML-Verarbeitung mit PHP
Weiter
XSL Transformations (XSLT) Die Transformation von XML-Daten in ein anderes Format, das beispielweise HTML oder PDF sein kann, ist aus der Entwicklung von Web-Applikationen kaum noch wegzudenken. Für diese Aufgabe bietet das World Wide Web Consortium die eXtensible Stylesheet Language (XSL) an. Diese besteht aus den drei Komponenten: ●
●
●
XSL Transformations (XSLT) bildet die eigentliche Programmiersprache zur Beschreibung von XML-Transformationen. Die XML Path Language (XPath) wird von XSLT genutzt, um auf XML-Dokumente beziehungsweise Teile davon zuzugreifen. XSL Formatting Objects (XSL-FO) werden genutzt, um Formatierungen zu beschreiben.
Vom Arbeitsprinzip her ist XSLT mit dem UNIX-Werkzeug awk verwandt: Bedingungen (Template Match) oder Funktionen (Template Name) werden nacheinander auf die Eingabe angewendet. Diese hat bei awk Zeilen, bei XSLT liegt sie als Baumstruktur vor. Wie awk kann XSLT nicht auf seine Ausgabe zugreifen. Beispiel 8.18: if-then-else in XSLT
Stylesheets, wie in XSLT geschriebene Programme aus historischen Gründen heißen, sind ihrerseits XML-Dokumente. Daher ist XSLT "geschwätzig", das heißt, sogar einfache Sprachkonstrukte erfordern viel Schreibarbeit. Beispiel 8.18 zeigt oben den nötigen Code, um ein if-then-else in XSLT zu realisieren, unten das hierzu äquivalente PHP-Schnipsel in Beispiel 8.19. Beispiel 8.19: if-then-else in PHP Wie die Document Style Semantics and Specification Language (DSSSL) für SGML ist XSLT eine funktionale Transformationssprache. Sie bringt daher die Nachteile funktionaler Programmiersprachen mit sich, beispielsweise den Umweg über Rekursion für das Ausdrücken von Schleifen oder Variablen, die eher konstant als variabel sind. Außerdem kann man die Vorteile der funktionalen Programmierung, etwa das Rechnen mit Funktionen als Datentypen oder die Programmierung mit Closures, nicht nutzen. Die bietet XSLT nicht. Ein weiterer Nachteil von XSLT liegt in der Domänenbeschränkung: Während XSLT "alles über XML weiß" und diesbezügliche Funktionen anbietet, weiß es relativ wenig von Dingen, die nichts mit XML
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.xslt.html (1 von 4)07.06.2005 21:49:10
XSL Transformations (XSLT)
zu tun haben. Ohne die Einbeziehung von in anderen Programmiersprachen, beispielsweise Java, geschriebenen Programmen über Callbacks können XSLT-Stylesheets nicht mit der Welt jenseits von XML interagieren. Das Beziehen von Daten aus anderen Quellen wie einer Datenbank oder das Erzeugen von nicht textbasierten Ausgabeformaten wie Grafiken oder PDF ist ohne Fremdhilfe nicht möglich.
Die PHP-Programmierschnittstelle für XSLT Abbildung 8.4. Die Klasse XSLTProcessor
PHP 5 bietet, angelehnt an die Programmierschnittstelle des Mozilla-Projektes, die Klasse XSLTProcessor (Abbildung 8.4) für die Aufführung von XSL-Transformationen an. Im Gegensatz zu den bereits vorgestellten XML-Programmierschnittstellen von PHP 5 ist die XSLT-Erweiterung in der Standardkonfiguration nicht aktiviert. Sie muss über --with-xsl bei der Konfiguration des BuildProzesses aktiviert werden (siehe Anhang A). Mit DOMDocument::load() werden in Beispiel 8.21 zunächst XML-Dokument (Beispiel 8.1) und XSLStylesheet (Beispiel 8.20) in je ein Objekt der Klasse DOMDocument geladen. Mit den Methoden importStylesheet() und transformToDoc() wird das XSL-Stylesheet-Objekt einem XSLTProzessor-Objekt zugewiesen sowie das Eingabedokument in ein neues Objekt der Klasse DOMDocument transformiert. Beispiel 8.20: XSL Stylesheet für den Buchkatalog
ISBN:
Beispiel 8.21: Transformation des Buchkatalogs von XML nach HTML mit XSLT http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.xslt.html (2 von 4)07.06.2005 21:49:10
XSL Transformations (XSLT)
Sebastian Bergmann Professionelle Softwareentwicklung mit PHP 5 ISBN: 3-89864-229-1
Hakan Kücükyilmaz PHP 5 ISBN: 3-89864-236-4
Alternativ stehen die Methoden transformToUri() und transformToXml() zur Verfügung, die das Transformationsergebnis in einer Datei abspeichern oder als String zurückliefern. Die Parameter des XSL-Stylesheets können über die Methoden getParameter(), setParameter() und removeParameter() kontrolliert werden.
Aufrufen von PHP-Funktionen aus XSLT heraus Über die XSL-Funktion php:function können beliebige PHP-Funktionen aus einem XSL-Stylesheet heraus aufgerufen werden. Dieser muss hierfür mit xmlns:php="http://php.net/xsl" den entsprechenden Namespace deklarieren (Beispiel 8.22). Über die Methode registerPHPFunctions () des XSLT-Prozessor-Objektes wird die Unterstützung für die Ausführung von PHP-Funktionen in XSL-Stylesheets aktiviert (Beispiel 8.23). Beispiel 8.22: Verwendung einer PHP-Funktion in einem XSL-Stylesheet
Beispiel 8.23: Transformation mit einem XSL-Stylesheet, das eine PHP-Funktion verwendet http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.xslt.html (3 von 4)07.06.2005 21:49:10
XSL Transformations (XSLT)
PHP 5 Zurück Document Object Model (DOM)
Nach oben Zum Anfang
Weiter Objekte mit dem XML_Transformer ins Web bringen
http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.xslt.html (4 von 4)07.06.2005 21:49:10
Objekte mit dem XML_Transformer ins Web bringen
Zurück
Objekte mit dem XML_Transformer ins Web bringen Kapitel 8. XML-Verarbeitung mit PHP
Weiter
Objekte mit dem XML_Transformer ins Web bringen Der XML_Transformer verfolgt die Lösung zweier Aufgaben, die nur auf den ersten Blick nichts miteinander zu tun haben. Zum einen suchen viele Entwickler nach einem eleganten Weg, um PHP-Objekte "ins Web zu bringen". Zum anderen ist die Transformation von XML-Daten aus einem Format in ein anderes bei der Entwicklung von Web-Applikationen allgegenwärtig. Im Gegensatz zu den XSL Transformations, die eines der oben genannten Teilprobleme lösen, erlaubt der XML_Transformer die prozedurale Definition von XML-Transformationen. Hierbei können sämtliche Fähigkeiten von PHP, wie beispielsweise der Zugriff auf Datenbanken oder die Erzeugung von Grafiken, genutzt werden. Das Ergebnis eines Zwischenschritts kann im Gegensatz zu XSLT direkt als Eingabe für den nächsten Schritt dienen. Abbildung 8.5. Installation von XML_Transformer pear install --alldeps XML_Transformer
Den XML_Transformer verwenden Im Wesentlichen besteht die Kodierung mit dem XML_Transformer aus der Nutzung vorhandener NamespaceHandler oder dem Schreiben eigener. In Beispiel 8.24 kommt der im Paket enthaltene Image NamespaceHandler zum Tragen. Dieser bietet unter anderem ein "intelligentes" -Element, das die width- und height-Attribute automatisch auf Basis der per getimagesize() erkannten Bildinformationen setzt. Hierzu werden zunächst die Klassen XML_Transformer und XML_Transformer_Namespace_Image geladen. Danach wird ein Objekt der Klasse XML_Transformer erzeugt, der img-Namespace wird im Konstruktor an die Klasse XML_Transformer_Namespace_Image gebunden. Die eigentliche Transformation wird von der Methode transform geleistet, der als einziger Parameter die XML-Eingabe als String übergeben wird. http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/programming-php.xml.xml-transformer.html (1 von 10)07.06.2005 21:49:12
Objekte mit dem XML_Transformer ins Web bringen
Beispiel 8.24: Intelligentes -Tag mit dem Image-Namespace-Handler