Der eingebaute Webserver in PHP 5.4
Mit PHP 5.4 kommt ein kleiner eingebauter Webserver mitgeliefert, der allerdings nur für Testzwecke genutzt werden soll, auf Produktionsmaschienen soll man ihn nicht einsetzen, die Performance ist nicht so der Hit (single threaded) und auch Features wie .htaccess Support (mod_rewrite etc.) und einiges andere fehlen.
Falls bei der Entwicklung oder auf einer Testmachine „mal eben schnell“ ein Script via Webserver getestet werden soll kann man sich die Installation eines „richtigen“ Webservers sparen, und einfach PHP selbst nutzen:
php -S localhost:8000
Damit wird das aktuelle Verzeichnis auf localhost Port 8000 verfügbar gemacht. Im aktuellen Verzeichnis liegt eine index.php. Rufe ich dies nun auf im Browser:
http://localhost:8000/
The requested resource / was not found on this server.
Eigentlich sollte nun die index.php ausgeführt werden. Unter Linux funktioniert das auch wunderbar, unter Windows war das wohl ein Bug den ich gefunden habe, der auch innerhalb eines Tages behoben wurde. Dann also direkt:
http://localhost:8000/index.php
Dies ist eine Test PHP Datei
Auf der Konsole sehe ich die folgende Ausgabe:
PHP 5.4.0beta2 Development Server started at Sat Oct 22 12:50:09 2011 Listening on localhost:8000 Document root is C:\Temp\php54beta2\public Press Ctrl-C to quit. [Sat Oct 22 12:50:18 2011] ::1:3216 [404]: / - No such file or directory [Sat Oct 22 12:50:18 2011] ::1:3218 [404]: /favicon.ico - No such file or directory [Sat Oct 22 12:50:18 2011] ::1:3219 [404]: /favicon.ico - No such file or directory [Sat Oct 22 12:50:18 2011] ::1:3220 [404]: /favicon.ico - No such file or directory [Sat Oct 22 12:50:24 2011] ::1:3227 [200]: /index.php [Sat Oct 22 12:50:40 2011] ::1:3239 [404]: / - No such file or directory [Sat Oct 22 12:50:51 2011] ::1:3249 [404]: / - No such file or directory
Soll nicht das aktuelle Verzeichnis genommen werden kann dies mit dem Parameter -t geändert werden:
php -S localhost:8000 -t C:/Temp/php54beta2/public
Da es keine .htaccess Unterstützung gibt, viele Projekte aber eine Regel haben die alle Requests auf ein Router-Script umbiegt, bietet der eingebaute Webserver diese Möglichkeit per Parameter:
php -S localhost:8000 C:/Temp/php54beta2/public/index.php
Im PHP Script kann man übrigens erkennen ob es durch den eingebauten Webserver aufgerufen wurde:
if (php_sapi_name() == 'cli-server') {
Zum Schluss noch 2 schnelle Performance-Tests mittels Apache Bench auf eine statische Datei und eine 1-zeilige PHP Datei (10000 Requests, 30 parallel, beides ohne APC):
PHP CLI Webserver:
index.php (24 Byte): 424 Requests/s
bild.png (185 Byte): 450 Requests/s
Apache Webserver:
index.php (24 Byte): 718 Requests/s
bild.png (185 Byte): 845 Requests/s
Bei diesen kleinen Dateien ist es also durchaus schnell, aber bei komplexeren Scripten und vielen parallelen Zugriffen wird er schnell langsamer, da sie wie gesagt seriell abgearbeitet werden.
Oh, prima das es der HTTP-Server in den Stable schafft! Bin ein großer Fan davon!
Persönlich werde ich das Ding wohl mehr als weiteren Server betreiben. Also nicht immer erst am Document Root rumschrauben, Server neu starten nur um irgendwas kleines zu testen.
Und vielleicht auch lokale selbstgebastelte „Services“ wo Performance und Sicherheit irrelevant sind.
Ab jetzt träume ich davon den in Zukunft auch produktiv als HTTP-Server zu nutzen! 😉
Etwas überspitzt: Wenn ich sowieso alles durch die index.php jage, wofür brauche ich dann noch einen richtigen Webserver?
Florian Heinze
24 Okt 11 at 10:24
@Florian: Puh, also ich möchte das HTTP Protokoll nicht selbst implementieren, und um so schöne Dinge wie $_POST, $_GET, verschiedenste Header und Dateiuploads $_FILES möchte man sich nun wirklich nicht selbst kümmern glaub ich. Ich glaube ganz viel mehr macht der Webserver in diesem Fall auch nicht oder?
Michael Kliewe
24 Okt 11 at 10:44
@Michael: Hm, ich hätte jetzt erwartet das es die $_* dort auch irgendwie gibt? In der Doku steht nix, im RFC (https://wiki.php.net/rfc/builtinwebserver) ist in einem Beispiel $_SERVER[„REQUEST_URI“] zu sehen.
Ob es wirklich so aufwändig wäre die selber zu implementieren bin ich gar nicht so sicher? Etwas STDIN auslesen und ein bisschen parsen 😉 Bei $_FILES hat mich sowieso schon immer die Sortierung bei mehreren Dateien genervt! 😉
Teilweise hat man ja auch kaum noch echte Get-Parameter sonder parst die aus der Pfad-Angabe und das muss ich sowieso selber erledigen.
Florian Heinze
24 Okt 11 at 12:00
@Florian: Ich glaube ich habe dich missverstanden.
„Etwas überspitzt: Wenn ich sowieso alles durch die index.php jage, wofür brauche ich dann noch einen richtigen Webserver?“
Ich dachte du wolltest gar keinen Webserver mehr, sondern mittels PHP und socket_create() usw. selbst Port 80 aufmachen und dich drum kümmern. Aber nun glaube ich deine Frage war eher wo (außer beim Single-Thread-Problem) noch ein funktionaler Unterschied zwischen einem richtigen Webserver (Apache, nginx etc.) und dem eingebauten Webserver ist.
Michael Kliewe
24 Okt 11 at 12:18
Hehe, bin wieder schneller gewesen 😉
http://www.kingcrunch.de/blog/2011/07/27/eingebauter-webserver/
KingCrunch
24 Okt 11 at 12:25
@KingCrunch: Hab ja auch nicht behauptet der erste zu sein der dieses Feature „entdeckt“ hat 😉
Michael Kliewe
25 Okt 11 at 18:41
hm komisches ding 🙂 seh da nicht wirklich einen sinn darin.. wenn man schnell ein script testen möchte kann man ja auch die php cli verwenden oder? ausserdem kann man damit wirklich nur kleine scripts testen wenn .htaccess nicht unterstützt wird. sobald man ein framework wie zb cakephp verwendet fällt der eingebaute webserver schonmal aus..
christian
2 Nov 11 at 10:05
[…] Nun gibt es auch für Testzwecke einen eingebauten Webserver in PHP, einen guten Artikel findet ihr hier […]
PHP 5.4.0 veröffentlicht | Netw0rk.eu
4 Mrz 12 at 11:17
@christian mit dem CLI kann man die Seite aber nicht betrachten wie sie im Server aussieht, vorallem hat man kein $_GET, $_POST, $_SERVER etc, und selbst wenn man das nicht benutzen würde würde man bei einem CLI Aufruf die HTML-Daten direkt auf der Konsole ausgegeben bekommen was sich zum testen wohl nicht wirklich eignen dürfte.
Ich sehe ebenso wie Florian Heinze einen Nutzen darin wenn man selbst geschriebene Verwaltungstools laufen lassen will, die nicht auf dem Apache laufen sollten (z.B. ein Script mit dem man Apache neustarten kann ;)) und spezielle Berechtigungen brauchen, also Dinge, die man mit dem www-data-Benutzer nicht ausführen können sollte (der eingebaute Server läuft ja als root wenn man ihn als root startet).
Natürlich sollte man den Server dann z.B. an eine IP im VPN binden, da eine SSL-Verbindung vermutlich nicht möglich ist (konnte es bisher noch nicht testen weil PHP 5.4 zumindest bei CentOS noch nicht in den offiziellen Repositories ist).
Tobi
25 Mrz 12 at 03:10
[…] Extension. Details siehe Artikel bei Johannes oder im PHP Manual.E_ALL enthält nun E_STRICTEin kleiner eingebauter Webserver für Tests und Entwicklungsumgebungen. Ich hatte ja bereits hier im Blog darüber geschrieben.<?= ist nun immer verfügbar, auch wenn […]
PHP 5.4.0 released! Neue Funktionen | PHP Gangsta - Der PHP Blog mit Praxisbezug
6 Jun 12 at 00:29
[…] – aufgrund fehlender Funktionalität und mieser Performance durch serielle Abarbeitung. Michael Kliewe und auch Sebastian Krebs haben den Server getestet und ihre Ergebnisse bereits mit der Community […]
PHP 5.4 und sein Webserver(chen) - entwickler.de
28 Apr 15 at 16:16