topic: web (HTTP / $_GET / $_POST / form / php -S)
PHP を Web アプリ として動かすトピック。CLI で回していたコードを php -S localhost:8000 で立てた Web サーバー経由で ブラウザから叩く 形に拡張する。
このトピックで身につくこと
- リクエスト / レスポンスの往復を 1 行で説明できる
php -S localhost:8000で組み込みサーバーを立て、自作 PHP をブラウザに出せる- URL の
?name=...を$_GETで受け取れる - HTML form を書き、その送信を
$_POSTで受け取れる $_SERVER['REQUEST_URI']/REQUEST_METHODで簡易ルーターを書ける
前提知識の要点
連想配列が読める / echo が書ける の 2 点だけあれば始められる。$_GET / $_POST / $_SERVER は PHP が自動で作る スーパーグローバル (= どの関数からでも読める連想配列)。
<?php
$name = $_GET['name'] ?? 'guest';
echo "こんにちは、{$name}さん\n";??(null 合体) は「あればそれ、無ければ右側」。URL に?name=...が無いケースに強くする定石$_GET/$_POST/$_SERVERの中身も結局はただの連想配列。アクセスは$arr['key']と同じ
| 変数 | 何が入っているか | 例 |
|---|---|---|
$_GET |
URL の ?key=value&... を分解した配列 |
?name=太郎 → $_GET['name'] |
$_POST |
method=post で送られた値 |
<input name="msg"> → $_POST['msg'] |
$_SERVER |
リクエスト全般のメタ情報 | $_SERVER['REQUEST_URI'] / REQUEST_METHOD |
chapter 一覧
| # | chapter | 内容 |
|---|---|---|
| 1 | ch01-what-is-web/ |
Web / HTTP / GET vs POST (ドリルなし) |
| 2 | ch02-builtin-server/ |
php -S で組み込みサーバーを立てる |
| 3 | ch03-get-params/ |
$_GET でクエリを受け取る |
| 4 | ch04-post-params/ |
$_POST でフォーム送信を受け取る |
| 5 | ch05-html-form/ |
<form> を組み立てて送信する |
| 6 | ch06-routing-basic/ |
REQUEST_URI / REQUEST_METHOD による分岐 |
合計 6 chapter / 12 drill / 所要 2.5〜3 時間。
採点と「本物の Web」の二段構え
$_GET / $_POST は 本来 ブラウザ + Web サーバー経由でしか埋まらない。しかし採点ランナーは CLI で php answer.php を直実行する。そこで本トピックの drill は次の方針で書く。
- 採点用スタブ で stdin からクエリ文字列を読み、
parse_strで$_GET/$_POSTを組み立てる - 採点ランナーが
tests/input.txtを stdin に流し込む → CLI でも$_GETが埋まった状態を再現できる - 本物の動作確認 は各 chapter の README で
php -S localhost:8000を案内する
<?php
// 採点用: stdin に "name=太郎&age=20" を流し込む
$query = trim(fgets(STDIN) ?: '');
parse_str($query, $_GET);
// 以降は本物の Web アプリと同じ書き方
$name = $_GET['name'] ?? 'guest';
echo "こんにちは、{$name}さん\n";「学習者はブラウザで体感、採点は CLI で検証」。両方やって初めて「Web アプリの中身」が腹落ちする。
進め方
- 各 chapter の
slide.mdを読む (4〜5 分) drill/の問題を順番に解く (ch01 は読むだけ)- 採点:
php scripts/grade.php topics/web/<chapter>/drill/<drill>/ - 余裕があれば
php -S localhost:8000でブラウザ起動を試す
つまづきポイント
| 症状 | 多くの原因 |
|---|---|
$_GET['name'] が null で落ちる |
URL に ?name=... が無い / stdin スタブに query を流していない |
| ブラウザでは動くのに採点 FAIL | 採点用 stdin スタブを消した、または出力に余分な HTML が混ざる |
php -S が 404 |
起動ディレクトリと PHP ファイルの場所がズレている |
| form 送信しても何も起きない | <form action="..."> の遷移先 PHP が違う |
$_POST が空 |
form の method が get になっている / name 属性を書き忘れ |
| ルーティングが分岐しない | REQUEST_URI には query string も含まれる。parse_url(..., PHP_URL_PATH) で path だけ取る |
関連トピック
| トピック | 関係 |
|---|---|
| array-assoc | $_GET / $_POST は連想配列 |
| session-cookie | Web の状態管理 (ログイン / カート) |
| db | フォームで受けた値を DB に書き込む |
| file-io | アップロード / 設定ファイル読み込み |
トピックを並列で参照する全体地図は TOPICS_INDEX.md にある。
案件 (dojo_map.tsv) での参照
topic_slug chapter_dir
web topics/web/ch02-builtin-server
web topics/web/ch03-get-params
web topics/web/ch04-post-params
web topics/web/ch05-html-form
web topics/web/ch06-routing-basic
slug web で参照可。12-web / web どちらの path でもアクセスできる (シンボリックリンク)。