# ch02 — `php -S` 組み込みサーバー / ブラウザで動作確認

Source: https://php-school.pages.dev/topics/web/ch02-builtin-server/
Site: AIと学ぶPHPの学校 (https://php-school.pages.dev)
Lesson: Web アプリ入門
Level: L4

Reference (official): https://www.php.net/manual/ja/reserved.variables.request.php

## 本文

# ch02 — `php -S` 組み込みサーバー / ブラウザで動作確認

## 概要

PHP には `php -S localhost:8000` という **組み込みの Web サーバー** が標準で付いている。Apache や Nginx を別途入れずに、コマンド 1 発でローカルに Web サーバーが立ち、ブラウザから自作の PHP にアクセスできる。学習・開発用として最高に手軽で、本番運用は別物 (Apache/Nginx + PHP-FPM) と覚えておけばよい。

起動時の 2 つ目の引数として **ルーター用の PHP ファイル** を渡せる。このルーターが全リクエストを受け取り、`$_SERVER['REQUEST_URI']` (今アクセスされている URL のパス) を見て応答を分岐させる。`/hello` なら挨拶、それ以外は 404、という世界一小さな Web アプリがここで書ける。

このチャプターのドリルは、CLI 採点ランナー上で動かすために `$_SERVER['REQUEST_URI']` を **stdin から組み立てるスタブ** が冒頭に入る。`php -S` で動かすときはスタブが効かず本物のリクエスト由来の値が使われる、という二重構造。「採点用のおまじない」として読み飛ばして OK。

## 学習目標

- `php -S localhost:8000` で **PHP 組み込みの Web サーバー** を立てられる
- ブラウザで `http://localhost:8000/...` を開いて自作 PHP を表示できる
- リクエストの **パス (`$_SERVER['REQUEST_URI']`)** で応答を分けられる

## 所要時間

スライド 5 分 + ドリル 1 問 = **15 分**

## ドリル

| no | 内容 |
|---|---|
| 01 | リクエストパスが `/hello` なら `"Hello, Web!"`、それ以外なら `"404"` を出力 |

## 本物の動作確認 (任意・推奨)

実際にブラウザでも動かしてみたい場合:

```bash
# ドリルの answer.php がある場所に行く
cd topics/web/ch02-builtin-server/drill/01-respond-text/

# 組み込みサーバー起動 (Ctrl+C で停止)
php -S localhost:8000 answer.php
```

ブラウザで以下を開いて挙動を確認:

- `http://localhost:8000/hello` → `Hello, Web!`
- `http://localhost:8000/nope` → `404`

採点ランナーは CLI 直実行なので、`answer.php` の冒頭で **stdin から `$_SERVER['REQUEST_URI']` を組み立てるスタブ** が入っている。Web で動かすときは「stdin が無いので `$_SERVER['REQUEST_URI']` を上書きしない」分岐になっていて、本物のリクエスト由来の `$_SERVER['REQUEST_URI']` がそのまま使われる。**「Web で動かす分にはスタブを消して良い」** という前提のおまじないとして理解する。

## スライド

---
marp: true
theme: dojo
paginate: true
size: 16:9
---

<!--
LLM_CONTEXT:
  Lesson 12 / Chapter 2
  目的: php -S で組み込みサーバーを起動し、ブラウザで自作 PHP を表示する / $_SERVER['REQUEST_URI'] で分岐
  扱わない: $_GET (ch03) / $_POST (ch04) / form (ch05) / 本格的なルーティング (ch06)
  読み上げ時間目安: 4 分半
-->

# `php -S` 組み込みサーバー

Lesson 12 / Chapter 2

---

## PHP には Web サーバーが**入っている**

```bash
php -S localhost:8000
```

- Apache や nginx をインストールしなくても、**PHP だけで** Web サーバーが立つ
- `localhost:8000` の `8000` は **ポート番号** (好きに変えて良い)
- 立てたあとブラウザで `http://localhost:8000/` を開けば、その場のディレクトリの PHP が動く

→ 開発・学習用としては最も手軽。本番では使わないが、本コースでは**これだけで十分**。

---

## 1 つの PHP を「全リクエストの受け口」にする

```bash
# 起動: index.php をルーター扱いにする
php -S localhost:8000 index.php
```

- 第 2 引数にファイルを指定すると、**全てのリクエスト** がそのファイルに来る
- どの URL でも `index.php` が呼ばれる
- 分岐は `$_SERVER['REQUEST_URI']` を見て自分で書く

→ これが「1 ファイルで Web アプリ」のミニマム構成。

---

## `$_SERVER` で「今のリクエスト」を知る

```php
<?php
echo $_SERVER['REQUEST_METHOD']; // "GET" / "POST" / ...
echo $_SERVER['REQUEST_URI'];    // "/hello?name=taro"
```

| キー | 中身 | 例 |
|---|---|---|
| `REQUEST_METHOD` | HTTP メソッド | `"GET"` / `"POST"` |
| `REQUEST_URI` | リクエストされた URI | `"/hello?name=taro"` |
| `HTTP_HOST` | ホスト名 | `"localhost:8000"` |

- `$_SERVER` も **PHP が自動で作る連想配列** (スーパーグローバル)
- 中身はリクエストごとに違う

---

## URI で応答を分けるミニ例

```php
<?php
if ($_SERVER['REQUEST_URI'] === '/hello') {
    echo "Hello, Web!\n";
} else {
    echo "404\n";
}
```

- `/hello` に来たら挨拶
- それ以外は `"404"` と返す
- これだけで「ルーター」の最小版

---

## 採点用スタブのおまじない

```php
<?php
// 採点ランナーは CLI 直実行なので、stdin で REQUEST_URI を渡す
$line = trim(fgets(STDIN) ?: '');
if ($line !== '') {
    $_SERVER['REQUEST_URI'] = $line;
}

// 以降は本物の Web と同じ
if ($_SERVER['REQUEST_URI'] === '/hello') {
    echo "Hello, Web!\n";
} else {
    echo "404\n";
}
```

- stdin で来た 1 行を `REQUEST_URI` にセット → CLI でも分岐をテストできる
- 本物の Web で動かすときは stdin が空 → スタブは何もせず、PHP が埋めた `REQUEST_URI` がそのまま使われる
- **「採点と本物の両方で動かせる小細工」** と理解する

---

## このチャプターでできるようになること

✅ `php -S localhost:8000` で組み込みサーバーを立てられる
✅ ブラウザで自作 PHP を表示できる
✅ `$_SERVER['REQUEST_URI']` でリクエストパスを取れる
✅ 簡単な URI 分岐を書ける

→ ドリルへ
