PHP ビルトイン Web サーバー

CLI 版 PHP に搭載されている Web サーバ機能についてまとめています。

PHP 5.4.0 より、開発向けに PHP を簡単に Web 動作させるため、
簡易 Web サーバが備わっています。


公式サイト

ビルトインウェブサーバー | PHP


注意

公式サイトのページにも記載があるとおり、
インターネット上での公開向けに使用する事を考慮されていません。

特に ホスト名に関係なく IP アドレス参照で動作する環境の場合(自宅サーバ・VPS など)
php -S 0.0.0.0:80 によって制限なく公開すると、
IP アドレスで参照している悪質な参照で PHP の攻撃を受けますので、絶対にしないで下さい。
ネット上に公開する場合はバーチャルホストに対応し、ホスト名で参照を制限できる
🎈 Caddy などの Web サーバを経由して PHP 動作する事を推奨します。

🎈 Fly🎈 Glitch🎈 Google Cloud Run など、
システムレベルでサーバ名のみに参照が制限されている場合、
上記で懸念される IP アドレスレベルでの参照・攻撃の恐れはありません。
特に 🎈 Glitch はインストール済みの PHP を使用する必要があり、
また、使用しているメモリを少なくしてレスポンスを速くするため、
あえてビルトイン Web サーバを用いて公開しているプロジェクトもいくつか存在します。
ただし、独自ドメインの設定をしている場合は、 wp-login.php などの参照・攻撃が発生します。


起動・停止

公開ルートディレクトリへ cd した後 php -S 127.0.0.1:(ポート) とします。
(PHP 公式サイトでは localhost:(ポート) で記載されていますが、
 OS によって参照に問題がある場合があるようです)
次の場合 public_html 下を http://127.0.0.1:8080/ で参照できるようにします。

cd public_html/
php -S 127.0.0.1:8000

Web ブラウザなどで http://127.0.0.1:8000/ で参照します。
CtrlC で停止します。
参照ページは標準出力でログ表示されます。


設定・オプション

php へのオプションと php.ini の設定になります。

-S (–server) サーバの起動

-S または --server につづき、
参照(listen)対象の IP アドレス:ポート番号 を設定します。
IP アドレスは 0.0.0.0 ですべてを受け付けます。
IPv6 で指定する場合は [~] で囲みます。
IP アドレスの代わりにホスト名も指定できます。

php -S localhost:8080

-t(–docroot)ドキュメントルート

-t または --docroot に続き、ディレクトリの場所を指定します。
省略されている場合は現在のカレントディレクトリがドキュメントルートになります。
そのため、php 起動前に cd ドキュメントルート する方法もあります。

php -S localhost:8080 -t public_html/

-f(–file)実行ファイルの設定

-f または --file に続き、 ファイル名 を指定した場合、
ビルドイン Web サーバーでは参照される度にそのファイルを実行するようになります。
-f および --file は省略でき、単に ファイル名 を指定できます。
他のオプションを指定する場合、その後ろに ファイル名 を入れて下さい。

php -S localhost:8080 -t public_html/ index.php

-c(–php-ini)php.ini の位置

-c または --php-ini に続き、 php.ini の場所・ファイル名を指定します。
ディレクトリ名のみであれば、その場所の php.ini を参照します。

php -S localhost:8080 -c C:\php\php.ini
php -S localhost:8080 -c /opt/php/

環境変数 PHP_CLI_SERVER_WORKERS

PHP 7.4 より環境変数 PHP_CLI_SERVER_WORKERS に起動するワーカー数を指定し
php 起動する事で、複数のワーカーをフォークし、並列処理が可能になっています。


拡張子・index ファイル

.php 以外にもいくつかの拡張子をサポートしています。
この拡張子は該当する標準の MIME-Type を返します。
2020年3月現在、PHP 公式サイトに記載のある拡張子は次のとおりです。

.3gp .apk .avi .bmp .css .csv .doc .docx .flac .gif .gz .gzip .htm .html .ics .jpe .jpeg .jpg .js .kml .kmz .m4a .mov .mp3 .mp4 .mpeg .mpg .odp .ods .odt .oga .ogg .ogv .pdf .png .pps .pptx .qt .svg .swf .tar .text .tif .txt .wav .webm .wmv .xls .xlsx .xml .xsl .xsd .zip

PHP 5 系(サポート期限切れ)ではバージョンにより拡張子の対応が異なる事にご注意下さい。

上記に .php を該当するファイルがない場合、またはファイルを省略している場合、
そのディレクトリ内にある index.php または index.html を参照します。
下層ディレクトリの場合でどちらもない場合、
親ディレクトリの index.php または index.html を参照します。
公開ルートディレクトリにもなければ 404 Not Found を返します。

この動作により、ファイルがなければ index.php を参照するので、
index.php で URI に応じて処理を分岐したり、
PHP フレームワークや CMS などを動作させる事が可能です。


.php での特殊な動作

phpファイル.php を指定して起動した場合、
その ファイル.php では、条件によって FALSE で返すと、そのファイルを探します。

<?php

if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) {
    return false;
} 

Q&A

普通に HTML と画像などがある Web サイトも表示できるのですか?

はい。可能です。index.html などがあるディレクトリへ cd し、
php -S 127.0.0.1:8080 で起動した後、http://127.0.0.1:8080/ で参照してみて下さい。
ただしファイルがない場合は index.html を参照する事に注意を要します。

.htaccess は動作しますか?

動作しません。 .htaccess は Apache 特有の機能です。

Not Found を任意の表示にできますか?

ファイルがない場合は index.php を参照するので、
index.php で処理できます。

<?php

$uri = $_SERVER["REQUEST_URI"];

if ( ($uri == "/") ||
     ($uri == "/index.html") ||
     ($uri == "/index.php") ) {
  print "Hello!\n"; // トップページの出力

  exit;
}

http_response_code (404);
print "404 Not Found\n"; // Not Found の出力

JavaScript を用いて index.html 処理も可能ですが、
この動作は Web ブラウザに制限されます。

index.php と index.html 両方ある場合、どちらが優先されますか?

PHP 7.4.3 現在、 index.php が優先表示されます。

.html ファイルに PHP のコードは動作しますか?

動作せずにそのまま出力される事を確認しています。

http の標準ポート 80 で使用できますか?

可能ですが、すでに何だかの Web サーバがポート 80 で動作している場合は
起動する事ができません。IIS や Apache が動作している場合があります。

index.php で受け取れない URI があります。

Bug #61286 If the trailing path that follows a script contains a dot PATH_INFO is not set | PHP

. を含んでいる場合は物理的なファイルを探す仕様になっています。
例えばアドレスが robots.txt で終わる場合、
index.php は動作せず、実際の robots.txt ファイルを参照します。

拡張子などの動作を追加・変更できますか?

php 記載で ファイル.php を含めて起動する事で、
ファイル.php で任意の処理を行う事ができます。

ビルトインサーバと他の Web サーバを判別する方法は?

変数 $_SERVER['SERVER_SOFTWARE']PHP 7.4.3 Development Server となります。
7.4.3 はバージョン番号なので、バージョンで変化)
この変数でサーバの判別が可能です。

SSL に対応しますか?

PHP ビルトインサーバ自体は TLS(SSL)サーバ証明書の設定に対応していません。
開発目的なので、想定されていません。

🎈 Fly🎈 Google Cloud Run での使用や 🎈 Caddy を経由するなど、
SSL 対応のサービス・アプリの使用で SSL 化が可能です。