
als Komplettpaket ausliefern und nicht als „lose“ Sammlung von Dateien. PHP-Anwendungen bestehen nicht mehr nur aus wenigen HTML-Seiten, einigen PHP-Skripten und einer Datenbank. Insbesondere im Enterprise-Umfeld finden sich Anwendungen mit mehreren hundert Klassen-, Template-, HTML- und XML-Dateien. Beim Ausrollen einer derartigen Anwendung muss dann natürlich darauf geachtet werden, dass keine Datei „verloren“ geht. Dazu gibt es sicherlich verschiedene Automatismen. Aber wäre es nicht viel einfacher, alle für die Laufzeit notwendigen Dateien in nur einer Archiv-Datei zu bündeln und dann zu verteilen?
|
Mit der PHAR-Erweiterung für PHP stellt dies kein Problem mehr dar. Es handelt sich hierbei nicht um eine komplett neue Errungenschaft, denn schon seit 2005 gibt es das PEAR-Paket PHP-Archive, was sich zum Ziel gesetzt hat, PHP-Anwendungen gebündelt und in komprimierter Form in nur einer Datei auszuliefern. Jedoch sind in PHP programmierte Erweiterungen selten so schnell, wie in C programmierte. Daher wurde in 2007 mit der Entwicklung der PECL-Extension phar begonnen. Mittlerweile ist diese Extension fest in PHP 5.3 integriert und aktiviert. In diesem Artikel wird die Benutzung dieser Erweiterung beschrieben.
Zunächst muss sichergestellt werden, dass der php.ini-Parameter phar.readonly auf Off gesetzt ist, um schreibenden Zugriff auf PHARs zu ermöglichen. Dieser Parameter ist standardmäßig auf On gestellt und muss umgesetzt werden. Die Erzeugung eines PHAR geschieht über die Klasse Phar und ist in Abbildung 1 zu sehen. Mit nur zwei Code-Zeilen wird aus dem Inhalt des Verzeichnisses appl eine PHAR-Datei erzeugt. Diese kann nur mit PHP-Mitteln verändert oder wieder dekomprimiert werden. Mit dem Aufruf der Methode convertToExecutable(Phar::ZIP) auf das PHAR-Objekt kann diese in ein komprimiertes Format umgewandelt werden. Diese Datei kann dann mit einem beliebigen ZIP-Programm (z. B. WinZIP) bearbeitet und eingesehen werden. Eine Verarbeitung müsste dann aber mit Mitteln der ZIP-Extension gehandhabt werden.
Liegt bereits ein PHP-Archiv vor, so kann es zur Benutzung eingelesen werden. Dazu wird wieder ein Objekt vom Typ Phar erzeugt und dem Konstruktor werden diesmal drei Parameter übergeben. Der erste Parameter ist wieder der Pfad zur Datei. Als zweiter Parameter wird 0 übergeben. Im dritten Parameter definieren wir einen Alias-Namen. Mit diesem sprechen wir später das PHAR über den Streamwrapper phar:// an, der von der PHAR-Extension neu zur Verfügung gestellt wird. Auf diese Weise können einzelne Dateien direkt aus dem Archiv in einen bestehenden PHP-Code eingebunden und benutzt werden, so als ob diese im Dateisystem liegen würden. Dabei findet jedoch keine Dekomprimierung in ein temporäres Verzeichnis statt, sondern das PHAR bleibt unberührt. In Abbildung 2 ist ein Beispiel für das beschriebene Vorgehen zu sehen.
Im PHP-Archiv kann eine Stub-Datei eingefügt werden. Der Code dieses Stub wird automatisch ausgeführt, wenn das PHAR über die Kommandozeile gestartet oder über einen Webserver aufgerufen wird, was eine Anpassung der Webserver-Konfiguration für PHP voraussetzt. Bisher wurde noch keine spezielle Stub-Datei eingefügt, von daher hat PHP beim Erstellen des PHAR selbst einen minimalen Stub generiert, der nur aus der Anweisung __HALT_COMPILER() besteht. Sie ist zwingend erforderlich, um PHP daran zu hindern, die komprimierten Binärdaten des eigentlichen PHP-Archivs die nach dem Stub Code folgen, als PHP Code zu interpretieren. Auch bei selbst geschriebenen Stubs muss dies unbedingt als letzte Anweisung vorhanden sein. Abbildung 3 zeigt, wie ein PHAR mit einem eigenen Stub erstellt wird.
PHP kann einen Standard-Stub erzeugen (siehe Abbildung 4). Hier wird ein PHAR erstellt, der sich an der Kommandozeile und über Webserver gestartet anders verhält. Je nachdem wird eine unterschiedliche „Startseite“ aufgerufen. In diesem Fall entweder cli.php, wenn der Aufruf über die Kommandozeile erfolgt, oder web.php beim Aufruf über den Webserver. Die Methode createDefaultStub() bekommt als ersten Parameter den Dateinamen für den Kommandozeilenstart und als zweiten Parameter den Dateinamen für den Aufruf per Web übergeben. Auch die Methode setDefaultStub() kann zu diesem Zweck genutzt werden. Der Default-Stub hat den Vorteil, dass er den Aufrufmechanismus auswerten kann. Allerdings ist relativ viel Code im Stub vorhanden, was das PHAR etwas aufbläht. An dieser Stelle lohnt sich ein Blick in die PHAR-Datei mit einem Editor.
Eine Signatur innerhalb eines PHAR sichert es gegen Veränderungen außerhalb von PHP ab. Somit kann ein PHAR nicht mit einem Editor verändert werden, um z. B. das Verhalten des Stubs anzupassen. Wird dies dennoch getan, so kann das Archiv nicht korrekt eingelesen und benutzt werden. PHP erzeugt beim Erstellen eines PHAR immer eine Signatur, die mit der Methode getSignature() ausgelesen wird. Aktuell können fünf Signaturtypen genutzt werden, die über getSupportedSignatures() ermittelt werden können:
OpenSSL stellt hierbei sicherlich die interessanteste Methode dar. Das PHAR wird mit einem privaten Schlüssel signiert und kann nur mit dem zugehörigen öffentlichen Schlüssel geöffnet werden. Hierzu wird der private Schlüssel zunächst mit PHP-OpenSSL-Funktionen eingelesen, bearbeitet und anschließend der Methode setSignatureAlgorithm() mit dem Signaturtyp Phar::OPENSSL übergeben, wie in Abbildung 5 zu sehen. Das so signierte PHAR kann jetzt nur eingelesen werden, wenn der öffentliche Schlüssel in einer Datei parallel zum PHAR abgelegt wird und die Endung .pubkey hat. Liegt das Archiv also unter /pfad/zu/mein.phar, so muss der Dateiname des öffentlichen Schlüssels /pfad/zu/mein.phar.pubkey lauten.
Eine komplette Anwendung in einer einzigen Datei auszuliefern, ist sehr nützlich und bereits in der Java-Welt gang und gäbe. Nicht umsonst ähneln sich die beiden Abkürzungen PHAR (PHP-Archiv) und JAR (Java-Archiv) in gewisser Weise. Ein PHAR kann direkt von der Kommandozeile oder über einen Webserver ausgeführt werden, ohne dass die darin befindlichen Dateien entpackt werden müssen. Zum Aufrufen eines PHAR per Browser muss jedoch die Webserverkonfiguration entsprechend angepasst werden, so dass *.phar-Dateien durch PHP interpretiert werden.
Die Möglichkeit, PHP-Archive mittels OpenSSL zu signieren, erhöht die Vertrauenswürdigkeit und auch die Sicherheit bei der Handhabung. Mit der festen Integration der PHAR-Extension in PHP-Distributionen ab Version 5.3.0 ist PHP wieder einen weiteren Schritt nach vorne gegangen, um im Vergleich mit anderen Programmiersprachen mithalten zu können.