One of the coolest innovations in php 5.4 is a built-in server designed specifically for development and testing. Now you can write and test your code without having a full-fledged web server - just start the built-in server, test your code, and turn it off when you're done.
The server also provides the opportunity for creative use. For example, you can distribute a portable web application on CD or USB, or even as a desktop application created in PHP without using GTK or other graphical libraries.
The PHP manual emphasizes that the built-in server is designed for development and it is recommended not to use it on the combat server. There are no INI directives responsible for the server (except for coloring the output in the console), and it seems that the main idea of ​​the documentation: “we now also have a Web server, leave us alone”.
Despite this, I believe that embedded server can be a valuable tool for development and testing. For example, on my machine I use the pre-installed Apache with a custom configuration that is suitable for me, but sometimes I want to try some new Web applications. With the embedded web server, I can test the application directly from the “downloads” folder or temporary folder and move it to a normal environment only when it is needed.
But for a start, this is not so easy, because many written applications use .htaccess and mod_rewrite. But I'm sure that someone (maybe one of you, why not?) Will write an adapter for this, and I would like to be the first to test it.
In this article I will explain some basic examples of using an embedded server and show you how to make it useful for development and testing.
We use the built-in server
So, to use the server, we need php 5.4 or higher. To check the PHP version, run:
php -v
You can also determine if the server is available in your build by running:
php -h
and find the description of the "-S" and "-t" parameters, which are used only for the server.
To check the server, you can create an index.php file in the current directory that will contain a call to the phpinfo () function and then start the server:
[ec2-user@ip-10-229-67-156 ~]$ php -S 127.0.0.1:8080 PHP 5.4.0RC7 Development Server started at Fri Feb 26 18:49:29 2012 Listening on 127.0.0.1:8080 Document root is /home/ec2-user Press Ctrl-C to quit.
And now you can see the content sent by the embedded web server:

Each client request will be written to the console:
[Sun Feb 26 18:55:30 2012] 80.180.55.37:36318 [200]: / [Sun Feb 26 18:56:23 2012] 80.180.55.37:36584 [200]: /
Returning back, let's analyze the command line parameter "-S", which is used to specify the address from which the server will be accessible. Possible values:
localhost - the server will be accessible only from the local machine,
0.0.0.0 - on any machine interface,
Any external or gray IP - only on the specified IP
The "-t" parameter sets the specified directory "directory root". For example:
[ec2-user@ip-10-229-67-156 ~]$ php -S <localhost or your public IP>:8090 -t /home/ec2-user/public
Besides,. You can specify the name of a specific file router. For example:
[ec2-user@ip-10-229-67-156 ~]$ php -S >localhost or your public IP>:8080 -t /home/ec2-user/public public/index.php
The output of this router will be parsed and executed by the server. A simple example:
<?php $extensions = array("php", "jpg", "jpeg", "gif", "css"); $path = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH); $ext = pathinfo($path, PATHINFO_EXTENSION); if (in_array($ext, $extensions)) {
If the script returns FALSE, then the requested URI will be processed by the server that will issue the requested resource, or will return a 404 error. If the script returns anything else, the output of the script is passed to the client.
Although this approach gives us more control, there are a few things you should know. First, the PHP server gives only a minimal set of HTTP headers:
Connection: closed Content-Type: text/html Host: aws-dev-01.vtardia.com X-Powered-By: PHP/5.4.0RC7
D
Compare this with the headers returned by the Apache server:
Accept-Ranges: bytes Connection: Keep-Alive Content-Length: 631 Content-Type: text/html Date: Sat, 04 Feb 2012 18:24:42 GMT Etag: "bbb99-277-4ace8c5470a40" Keep-Alive: timeout=15, max=100 Last-Modified: Wed, 14 Sep 2011 15:54:09 GMT Server: Apache/2.2.21 (Unix) DAV/2
If your application uses headers, then it should take into account the difference in the development-environment and in production.
Secondly, the embedded server has another SAPI (Server API). Thus, by routing in index, php you can determine the script to be accessed on a test or combat server. php_sapi_name () will return the “cli-server” on the embedded server:
<?php if (php_sapi_name() == "cli-server") {
There is one special INI directive - cli_server.color. This directive returns the colored output to the console. Create an empty file called
cli-server.ini and paste this line:
cli_server.color = on
You can create a unique environment configuration for your server by specifying the necessary directives in your INI file. Undeclared directives will accept default values. Now we have declared only one directive -
cli_server.color .
Start the server with the parameter "-c" indicating the INI file:
[ec2-user@ip-10-229-67-156 ~]$ php -S localhost -c cli-server.ini
If your terminal supports colors, then you can see the “color” output in the console. 200 status will be highlighted in green, 404 in orange, and script errors will be highlighted in red.
Create a personal server
Now that you know everything you need to know about the built-in server, let's do something cool. Create your own portable server!
I will start with the following structure of our application:

The “library” folder contains the application code, “public” is the root directory, contains index.php and several static files. Particular attention in this guide will be given to the folder "server", and therefore our application will consist of a simple "Hello Word!" And a few pictures and css.
Our goal is to be able to start the server from the application directory with one command, and our server will take care of routing, HTTP headers and errors.
[ec2-user@ip-10-229-67-156 myapp]$ ./start.sh
Let's look at the startup script:
I assume that the script is launched from the application directory, so INIFILE, DOCROOT, ROUTER are defined using pwd. The path to php is determined using the which command. If php was not found in user $ PATH, then the script will terminate with an error.
This method works quite well, but let's give the user the opportunity to change any of the specified parameters from the command line, for example:
if [ ! -z $INIFILE ]; then INIFILE="$(pwd)/server/server.ini" fi
Let's continue, the “errors” folder contains files for HTTP error messages. Here is an example of the 403 error: although I used only HTML, the script will be included using the
include , so you can use any php code:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>403</title> </head> <body> <h1>403: Forbidden</h1> <p>Sorry, the requested resource is not accessible.</p> </body> </html>
Now look at router.php. The task of this file is to receive and manage all requests and transfer them to the server only if this file exists. All error pages are displayed by connecting a template.
<?php
In the first lines, I define some global parameters, such as DIRECTORY_INDEX, an error template directory. The date_default_timezone_set () parameter must match the OS settings, otherwise there will be inconsistencies between the records in the log and on the server. I also added a list of allowed IP addresses to increase security.
The logAccess () function is necessary, because when the routing script accepts the request, the server log is ignored by default. The function accepts only the status code, and the output format fully corresponds to the server format.
Our first task is a security check. If the client's IP is not in the array of allowed IPs, output an error message and exit the script. We need to give a status code different from 200 and the function header () will not work in here, so we use the new function - http_response_code.
If the client's IP is in the allowed IP array, then our next step is to get the requested path and file extension. If the extension is empty, we assume that the user is requesting a folder and we are building the path using the first defined DIRECTORY_INDEX.
Finally, if the requested file exists, we return FALSE, and allow the server to access the file. If not, a 404 error message is displayed.
Summary
It's all. As you can see, the php server is easy to use. Our personal server is very simple. The code can be optimized and included in more complex and functional classes. Happy coding!
ps With pleasure I will accept criticism and remarks to transfer to lichku.