PHP 5.4 Built In Webserver

One of the big features arriving with PHP 5.4 is the addition of a built-in basic webserver for use in development environments. Quite a few of the other scripting languages have something like this so I’m very pleased to see it in PHP. Using a server like this makes it easy to quickly try out some scripts without needing to configure apache or really do anything much! I had to look up a few things to get started, so I thought I’d write them down for posterity.

Get the Server Running

The server runs when you pass the -S switch to PHP on the command line. I had actually compiled PHP 5.4 alongside my existing PHP 5.3 installation, using instructions from an earlier post, and I just specified the full path to the version of PHP I wanted to run). You then supply the server name and port number:

php -S localhost:8080

This gives some initial output, and then information about each request as it comes in:

PHP 5.4.0RC7-dev Development Server started at Sun Jan 29 16:40:49 2012
Listening on localhost:8080
Document root is /home/lorna/test
Press Ctrl-C to quit.
[Sun Jan 29 16:40:55 2012] 127.0.0.1:46713 [200]: /
[Sun Jan 29 16:40:55 2012] 127.0.0.1:46714 [404]: /favicon.ico - No such file or directory

By default, the current directory is your webroot and you can now request whatever files are here, and run PHP in the usual way. You can also edit and save those files and re-request them without restarting the server, just as you would with a normal webserver (something I love about PHP).

The port number can be absolutely anything that you’re not already using, I’ve seen examples with 8080, 8000 and even 1337 – you can use whatever you like. If you pick a port that something else is using, you’ll see an error Failed to listen on localhost:8080 (reason: Address already in use)

Changing the DocRoot

If you want to run the server from one place and point it at a document root in another location, simply use the -t flag, followed by the path to the new docroot:

php -S localhost:8080 -t /var/www/awesomecode

Bear in mind that the webserver will run as the user you run this command as, so that user will need to have access to those files. Webservers such as apache often run as other users, but this one will probably run as you.

Routing Requests Like Apache Rewrite

One immediate feature that I was looking for was the ability to redirect all incoming requests to index.php, which I usually do with an .htaccess file. This webserver doesn’t support those (although my good friend Josh has created something pretty close) but it does support a routing file. There’s a great example in the manual of doing this which I used for reference. You create a file routing.php in the same directory and this becomes your front controller, looking like this:

   if (file_exists(__DIR__ . '/' . $_SERVER['REQUEST_URI'])) {
     return false; // serve the requested resource as-is.
   } else {
     include_once 'index.php';
   }

(this code taken entirely from this internals post as linked from the user contributed notes. It works like a charm but I can’t take the credit for it!)

This allows you to serve any files which are access by path in the usual way, but then redirect all other requests through to index.php. It’s such a common use case and I’m very pleased so see the examples already in the manual.

Changing the Host Name

You don’t have to call your server localhost; in fact, you might choose to give it another name and access it from other machines. To do this, simply add the new server name into /etc/hosts (or the equivalent for your system) and then start the server with the new name (I use my computer’s name)

php -S taygete:8080

This means that you can set up the same alias for another user and they can access your server – very neat!

Notes About the PHP Web Server

This makes a very neat quick way of throwing up a test site for a particular document root without any need to reconfigure apache or set up anything else. I’m using it to try out a few PHP 5.4 features without switching versions of PHP in and out of apache, and it works really well for that. It is only recommended as a development tool however, and isn’t intended for production use. That said, it’s a nice addition to the ever-impressive toolset of PHP and I’m happy to have it.

33 thoughts on “PHP 5.4 Built In Webserver

    • You must not set-up your nginx with fpm or whatever webserver you usually might set up for your development environment. Simply use the “watchr” gem to automatically restart the dev-server if files changed, and you’re done.

    • The built in server reduces the number of steps to developing a php web app. A lot of devs I know go and download MAMP/XAMP because it’s the easiest way to get a running web server. But those packages are a pain to work with and are generally a couple versions behind. The built in server allows you an easy way to use the latest version of php, while not having to worry about apache. Devs like to code – not setup apache instances..

  1. I think the paragraph about naming the hostname is entirely clear. If you bind a socket server on localhost, you can indeed only access it from your own machine. If you want the server to be accessible from any interface (wireless, wired, local, whatever), just specify:

    php -S 0.0.0.0:8080

    As for the ‘what’s the benefit’ questions.. for simply stuff it now becomes extremely easy for library / application developers to just include a ‘./launch.sh’ script to get an application running.

    This makes it very easy for people to evaluate software, without the user having to go through documentation that describes which php.ini settings need to be set, and webserver-specific configuration. Just ‘run and go’.

    Examples of other applications I’ve seen that do this is mercurial (hg serve) and gollum. I don’t know much about either Python or Ruby, so I was happy I could just fire up the command line and be up and running.

    I suspect that we’ll see a lot of applications that will start supporting this.

    Evert

    • Hi Evert, thanks for stopping to comment and adding the explanation of naming the server. I have been grateful for having those instant servers on other (especially unfamiliar) platforms and I hope that the same feature in PHP will be a useful addition. It’s early days for this feature but I like it so far!

  2. > As for the ‘what’s the benefit’ questions.. for simply stuff it now becomes extremely easy for
    > library / application developers to just include a ‘./launch.sh’ script to get an application running.

    Apart from the fact that everyone is telling you that it shouldn’t be used for production, which means this will always be the non-recommended way of running an application, and you still want to install a normal webserver in case you actually want to use it in production. Also, there are differences between, say, Apache and this built-in webserver, which means that code has to be written for both, although you’ll only ever use a normal webserver for production.

    I don’t see much benefit, except for the one-off case where someone wants to see a quick demo of software on their own machine. That said: I don’t think it’ll hurt to have it, either.

    • Well it may be the case that it’s not recommended for production, I don’t see a problem with using it for personal use. 1-user only stuff. I fully understand the server is not meant to scale.

      I for one am developing a CalDAV/CardDAV server, and I will totally include a launcher for this. Makes for extremely easy evaluation of a product. Because it’s relatively a bit difficult to setup a server, I’m worried I may miss potential users because they’re unable to get over the initial hurdle.

      But if they have a running server this quickly, they may be more inclined to invest the time to set it up properly, with a real webserver.

      If there’s indeed a difference between the built-in webserver and other sapi’s, it should be relatively easy to account for this.

  3. Also, there is a .htaccess parser for the builtin server called HTRouter. It can be found at https://github.com/jaytaph/HTRouter

    I don’t think it’s a useful module due to the recommendations of not using the webserver for production purposes, and even the author has stated this. However, I think that somehow the webserver can be updated in a near future to be stronger and more reliable so we can use it in small projects and low load environments.

    Best regards!

  4. Just to clarify a point which has already been briefly mentioned. You’re not naming the server with -S you’re telling it which interface to bind to. As mentioned previously ‘localhost’ will have it bind to the loopback address (127.0.0.1). A string name will bind it to the IP address that the supplied hostname resolves to, if you have no alias in your hosts file you could get odd results. The daemon itself does not care what hostname is being used to access it, it just uses specified argument to determine which address it should bind to. If you name your host ‘taygete’ it will bind to the IP specified by your local resolver (either hosts or another DNS service) for that hostname, but, anyone who access that IP either directly or via their own alias, ‘not-taygete’ as an example, would still reach your app (dependant on network configuration of course).

    Cheers

    On another quick note, you can use any port you want, but, always remember you need to be running as root to bind to a privileged port (anything under 1024)

  5. Pingback: Lorna Mitchell’s Blog: PHP 5.4 Built In Webserver | Scripting4You Blog

  6. I would like to know if this internal web server has some probes and hookes that can be used from within PHP.
    Some of the probes I would need is when the request started, so that I can calculate the duration used bandwidth for a given request. then I would appreciata a better diagnostics if something at the HTTP level goes wrong (user aborted upload, TCP connection dropped, ….).

    Peter

  7. Pingback: PHP 5.4 Built In Webserver | LornaJane | v3k.net | Scoop.it

  8. Pingback: » PHP 5.4 Officially released : Professional PHP Developer – Jose da Silva

  9. @Nilambar:

    An excellent example of a single-user application would be something like a local installation of PHPMyAdmin. Though PHPMyAdmin isn’t really my cup-of-tea, I can certainly understand some people being attracted to the idea of running it locally via the PHP 5.4 built-in webserver. While I think there are better ways to access a MySQL instance, I wouldn’t fault someone that was comfortable with the tool.

    –Wil Moore III

  10. Even with routing defaulting to index.php, phpMyAdmin will not working properly unless the path is ending with a slash.

    E.g.
    [code]http://localhost/phpMyAdmin/setup[/code] –> doesn’t work properly (css and js not loading properly).

    [code]http://localhost/phpMyAdmin/setup/[/code] –> works properly.

    Any way to get the router to insert that last slash?

  11. Pingback: Utilizzare il PHP Webserver su Windows - KLODEblog.DEV

  12. Pingback: Introducing Whippet - dxw

  13. in “Routing Requests Like Apache Rewrite” you don’t mention that you *also* need to specify the routing.php file on the command line when you run the server.

    I think it’s worth pointing it out in the article for the people who don’t bother reading the ‘manual’ you reference.

  14. Pingback: Testando rapidamente projetos PHP, com Vagrant, com Docker ou com Servidor Web Embutido -

  15. Pingback: How to Quickly Test and Run PHP Projects Using Vagrant, Docker or a Built-in Web Server | iMasters Expert - The Developer's Blog

  16. Thanks documenting this and walking us through it. I have question regarding how to start the PHP built-in web server automatically, as part of the machine start-up process, for instance.

    I have a small PHP application that I wish to run locally on a Linux Lite pc. Is it enough to include the php -S command in rc.local? Do I need to have a nohup with that in order for the server to continue running?

    I’m thinking that if I can get the server to start automatically when the machine boots up, then all I have to do is give the user a bookmark like localhost:8000/myapp/index.php and they can then run the application script very easily.

    Thanks again.

    • That would probably work although I’m not sure how you would make sure it was still running – I’ve used upstart for this kind of thing but I am much more familiar with supervisord so that would be my recommended approach. Why not just try it? Add a route which just calls exit() in PHP and see if the webserver comes back up again …. don’t forget to let us know if that works and which option you go with!

Leave a Reply

Please use [code] and [/code] around any source code you wish to share.

This site uses Akismet to reduce spam. Learn how your comment data is processed.