Встроенный web-сервер

Начиная с версии PHP 5.4.0 модуль CLI SAPI содержит встроенный web-сервер.

Этот web-сервер предназначен для использования при разработке и не должен использоваться на обычном сервере.

Запросы обслуживаются последовательно.

URI запросы обслуживаются из текущей директории, в которой был запущен PHP, если не используется опция -t для явного указания корневого документа. Если URI запроса не указывает на определенный файл, то будет возвращен либо index.php либо index.html в указанной директории. Если оба файла отсутствуют, то возвращается 404 код ответа.

Если PHP-файл указывается в командной строке, когда запускается веб-сервер, то он рассматривается как скрипт "маршрутизации". Скрипт выполняется в самом начале после каждого HTTP-запроса. Если этот скрипт возвращает FALSE, то запрашиваемый ресурс возвращается как есть. В противном случае браузеру будет возвращен вывод этого скрипта.

Стандартные MIME-типы возращаются для файлов со следующими расширениями: .css, .gif, .htm, .html, .jpe, .jpeg, .jpg, .js, .png, .svg, и .txt. Расширения .htm и .svg определяются начиная с PHP 5.4.4.

Пример #1 Запуск web-сервера

$ cd ~/public_html
$ php -S localhost:8000

В консоли выведется:

PHP 5.4.0 Development Server started at Thu Jul 21 10:43:28 2011
Listening on localhost:8000
Document root is /home/me/public_html
Press Ctrl-C to quit

После URI запросов http://localhost:8000/ и http://localhost:8000/myscript.html в консоли выведется примерно следующее:

PHP 5.4.0 Development Server started at Thu Jul 21 10:43:28 2011
Listening on localhost:8000
Document root is /home/me/public_html
Press Ctrl-C to quit.
[Thu Jul 21 10:48:48 2011] ::1:39144 GET /favicon.ico - Request read
[Thu Jul 21 10:48:50 2011] ::1:39146 GET / - Request read
[Thu Jul 21 10:48:50 2011] ::1:39147 GET /favicon.ico - Request read
[Thu Jul 21 10:48:52 2011] ::1:39148 GET /myscript.html - Request read
[Thu Jul 21 10:48:52 2011] ::1:39149 GET /favicon.ico - Request read

Пример #2 Запуск с указанием корневой директории

$ cd ~/public_html
$ php -S localhost:8000 -t foo/

В консоли выведется:

PHP 5.4.0 Development Server started at Thu Jul 21 10:50:26 2011
Listening on localhost:8000
Document root is /home/me/public_html/foo
Press Ctrl-C to quit

Пример #3 Использование скрипта маршрутизации

В этом примере, запросы изображений будут возвращать их, но запросы HTML файлов будут возвращать "Welcome to PHP".

<?php
// router.php
if (preg_match('/\.(?:png|jpg|jpeg|gif)$/'$_SERVER["REQUEST_URI"])) {
    return 
false;    // сервер возвращает файлы напрямую.
} else { 
    echo 
"<p>Welcome to PHP</p>";
}
?>
$ php -S localhost:8000 router.php

Пример #4 Проверка использования CLI web-сервера

Для совместного использования скрипта маршрутизации при разработке с CLI web-сервером и в дальнейшем с боевым web-сервером:

<?php
// router.php
if (php_sapi_name() == 'cli-server') {
    
/* Маршрутизация с заданными правилами и выход с возвращением false */
}
/* продолжение с обычными операциями index.php */
?>
$ php -S localhost:8000 router.php

Пример #5 Поддержка неподдерживаемых типов файлов

Если вам нужно обслуживать статические ресурсы с MIME типами неподдерживаемыми CLI web-сервером:

<?php
// router.php
$path pathinfo($_SERVER["SCRIPT_FILENAME"]);
if (
$path["extension"] == "ogg") {
    
header("Content-Type: video/ogg");
    
readfile($_SERVER["SCRIPT_FILENAME"]);
}
else {
    return 
FALSE;
}
?>
$ php -S localhost:8000 router.php

Пример #6 Доступ к CLI web-серверу с удаленных машин

Вы можете сделать web-сервер доступным на 8000 порту для всех сетевых интерфейсов:

$ php -S 0.0.0.0:8000

Коментарии

Автор:
On Windows you may find useful to have a phpserver.bat file in shell:sendto with the folowing:
explorer http://localhost:8888
rem check if arg is file or dir
if exist "%~1\" (
  php -S localhost:8888 -t "%~1"
) else (
  php -S localhost:8888 -t "%~dp1"
)

then for fast web testing you only have to SendTo a file or folder to this bat and it will open your explorer and run the server.
2013-07-10 23:03:40
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
In order to set project specific configuration options, simply add a php.ini file to your project, and then run the built-in server with this flag:

php -S localhost:8000 -c php.ini

This is especially helpful for settings that cannot be set at runtime (ini_set()).
2014-01-22 17:26:28
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
If your URI contains a dot, you'll lose the $_SERVER['PATH_INFO'] variable, when using the built-in webserver.
I wanted to write an API, and use .json ending in the URI-s, but then the framework's routing mechanism broke, and it took a lot of time to discover that the reason behind it was its router relying on $_SERVER['PATH_INFO'].

References:
https://bugs.php.net/bug.php?id=61286
2014-10-13 17:19:37
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
My routing file looks like this: 

if (file_exists($_SERVER["DOCUMENT_ROOT"] . $_SERVER["REQUEST_URI"])) {
    return false;
} else {
    require "index.php";
}

The reason is to support all static files.
2015-03-11 12:59:53
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
Note that to listen on a naked IPv6 address, you have to strangely enclose the address in so-called square brackets.  Example:

$ php -S [9990:116:a001:1900::1001]:8080 -t web/
2015-08-20 18:04:46
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
when I need to up a server for develop with rewrite, I use it:

// php -S 0.0.0.0:8080 -file webServer.php

// webServer.php
<?php
if (preg_match('/\.css|\.js|\.jpg|\.png|\.map$/'$_SERVER['REQUEST_URI'], $match)) {
   
$mimeTypes = [
       
'.css' => 'text/css',
       
'.js'  => 'application/javascript',
       
'.jpg' => 'image/jpg',
       
'.png' => 'image/png',
       
'.map' => 'application/json'
   
];
   
$path __DIR__ $_SERVER['REQUEST_URI'];
    if (
is_file($path)) {
       
header("Content-Type: {$mimeTypes[$match[0]]}");
        require 
$path;
        exit;
    }
}
require_once 
__DIR__.'/../app/bootstrap.php';
2016-02-26 14:48:29
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
Автор:
I improved Ivan Ferrer's phpserver.bat to open the Send To'd files in the browser directly:-

rem check if arg is file or dir
if exist "%~1\" (
  explorer http://localhost:8888
  php -S localhost:8888 -t "%~1"
) else (
  explorer http://localhost:8888/%~nx1
  php -S localhost:8888 -t "%~dp1"
)
2016-04-14 18:50:31
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
Автор:
It’s not mentioned directly, and may not be obvious, but you can also use this to create a virtual host. This, of course, requires the help of your hosts file.

Here are the steps:

1    /etc/hosts
    127.0.0.1    www.example.com

2    cd [root folder]
    php -S www.example.com:8000

3    Browser:
    http://www.example.com:8000/index.php

Combined with a simple SQLite database, you have a very handy testing environment.
2016-08-07 12:55:19
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
Do NOT use the -t option if you want to use a router script, you can change current working directory to the web document root before launching the php built-in web server.

[works fine]

cd /d C:\Web\Server
php -S www.51-n.com:80 router.php -n -d expose_php=0 -d display_errors=0 -d extension_dir="ext"

[always gets a 500 error]

php -S www.51-n.com:80 router.php -t C:\Web\Server -n -d expose_php=0 -d display_errors=0 -d extension_dir="ext"
2016-09-17 22:29:55
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
To output debugging information on the command line you can write output to php://stdout:

<?php
$path 
$_SERVER["SCRIPT_FILENAME"];

file_put_contents("php://stdout""\nRequested: $path");
echo 
"<p>Hello World</p>";
?>
2016-10-18 16:21:21
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
$_SERVER['SERVER_ADDR'] is not defined when using php as the built-in commandline web server, so you can not use $_SERVER['SERVER_ADDR'] to detect the Server's IP address.

P.S.: This is tested on Windows with PHP 7.1 on 2016-12-22.

Below is the printed $_SERVER variable.

Array
(
    [DOCUMENT_ROOT] => E:\Programs\PHPServer\www\srv
    [REMOTE_ADDR] => 118.117.61.32
    [REMOTE_PORT] => 10865
    [SERVER_SOFTWARE] => PHP 7.1.0 Development Server
    [SERVER_PROTOCOL] => HTTP/1.1
    [SERVER_NAME] => 0.0.0.0
    [SERVER_PORT] => 8080
    [REQUEST_URI] => /
    [REQUEST_METHOD] => GET
    [SCRIPT_NAME] => /index.php
    [SCRIPT_FILENAME] => E:\Programs\PHPServer\www\srv\index.php
    [PHP_SELF] => /index.php
    [HTTP_HOST] => www.wuxiancheng.cn:8080
    [HTTP_CONNECTION] => keep-alive
    [HTTP_CACHE_CONTROL] => max-age=0
    [HTTP_UPGRADE_INSECURE_REQUESTS] => 1
    [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    [HTTP_DNT] => 1
    [HTTP_ACCEPT_ENCODING] => gzip, deflate, sdch
    [HTTP_ACCEPT_LANGUAGE] => zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4
    [HTTP_COOKIE] => qbbs_2132_saltkey=fZ7509n5; qbbs_2132_lastvisit=1482156014; Hm_lvt_f812a4362ef73c80c4d13485d1ab3a49=1482159614; _ga=GA1.2.1594404236.1482159615; su=727vL6EEPLqjcyfJcad-za9eVYOh1i7e; Hm_lvt_6a65b0f2004e441e86ecea9c3562d997=1482232509,1482241896,1482242293,1482296586
    [REQUEST_TIME_FLOAT] => 1482390410.65625
    [REQUEST_TIME] => 1482390410
)
2016-12-22 09:09:41
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
I painfully experienced behaviour that I can't seem to find documented here so I wanted to save everyone from repeating my mistake by giving the following heads up:

When starting php -S on a mac (in my case macOS Sierra) to host a local server, I had trouble with connecting from legacy Java. 

As it turned out, if you started the php server with 
"php -S localhost:80" 
the server will be started with ipv6 support only!

To access it via ipv4, you need to change the start up command like so:
 "php -S 127.0.0.1:80"
which starts server in ipv4 mode only.
2017-01-11 15:43:15
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
Note: The built-in web server has a file size limit. For files larger than 5 GB, it will always serve a "File not found" error page.
2017-05-26 22:26:06
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
You can also print messages to the server's STDOUT via error_log().

Also the documentation doesn't make it clear that when you use router script if a PHP file is requested and you return false, the PHP file will be served (i.e. you do not need to load and eval it manually).
2017-06-29 10:16:27
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
Just a note to people who also use windows 8.1, or anyone who has had this problem when running the using the PHP server CLI.

`PHP -S localhost:8000 -t /public` <-- Not going to work.

`PHP -S localhost:8000 -t public` <-- Works!

And there is something else up in the notes saying something about you can't serve a project folder and a router file. Well, actually you can! At least for me.

`PHP -S localhost:8000 router.php -t public` <-- Perhaps someone tries this and it doesn't work.

`PHP -S localhost:8000 -t public router.php` <-- Works!
2017-08-10 02:53:29
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html
submit_btn.addEventListener(MouseEvent.CLICK, sendMessage);
function sendMessage(e:MouseEvent):void{
var my_vars:URLVariables = new URLVariables();
my_vars.senderName = name_txt.text;
my_vars.senderEmail = email_txt.text;
my_vars.senderMsg = message_txt.text;

var my_url:URLRequest = new URLRequest("mail.php");
my_url.method = URLRequestMethod.POST;
my_url.data = my_vars;

var my_loader:URLLoader = new URLLoader();
my_loader.dataFormat = URLLoaderDataFormat.VARIABLES;
my_loader.load(my_url);

name_txt.text = "";
email_txt.text = "";
message_txt.text = "Message Sent";

}
2017-10-18 18:40:59
http://php5.kiev.ua/manual/ru/features.commandline.webserver.html

    Поддержать сайт на родительском проекте КГБ