Slide 1

Slide 1 text

⾞輪の再発明をしよう! PHP で実装して学ぶ、Web サーバーの仕組みと HTTP の正体 PHPerKaigi 2026

Slide 2

Slide 2 text

⾃⼰紹介 名前:本多 宏謙(H1R0) 所属:BABY JOB株式会社 肩書き:ギャルマインド伝道師(⾃称) 趣味:お酒、ゲーム @H1R0728 エンジニア⼈⽣のほとんどを PHP と歩んできました

Slide 3

Slide 3 text

本発表のゴール ● Web サーバーの基本的な仕組みが理解できる ● ⾞輪の再発明をしたくなる

Slide 4

Slide 4 text

なんで PHP で Web サーバーを作ったのか そういえば Web サーバーの仕組みってどうなってるんだ? → ⾊んなドキュメントを読むも複雑で理解できず → 作った⽅が速いのでは?(AI ですぐ作れそうだし) → 慣れ親しんだ PHP のコードならすぐ理解できるはず!!

Slide 5

Slide 5 text

Gemini に実装させてみた Hello!"; // 5. ブラウザに送信して接続を閉じる fwrite($connected, $response); fclose($connected); } }

Slide 6

Slide 6 text

1. 待つ 接続を 待ち受ける 2. 読む リクエストを 読み取る 3. 返す レスポンスを 組み⽴てて返す Web サーバーの仕事の 3 ステップ

Slide 7

Slide 7 text

1. 接続を待ち受ける

Slide 8

Slide 8 text

ソケットの作成

Slide 9

Slide 9 text

接続を待ち受ける

Slide 10

Slide 10 text

ソケットとは ● 通信の出⼊り⼝のこと ○ クライアント側、サーバー側双⽅に存在する ○ ソケットを通すことでデータをやり取りする ○ IP アドレスとポート番号の組み合わせで通信相⼿を識別 ● サーバー側にはリスニングソケットと接続済みソケットが存 在する

Slide 11

Slide 11 text

接続の待ち受け サーバー リスニングソケット クライアント1 クライアントソケット クライアント2 クライアントソケット 接続要求 接続要求

Slide 12

Slide 12 text

接続の受け⼊れ サーバー リスニングソケット クライアント1 クライアントソケット クライアント2 クライアントソケット 接続済みソケット1 接続済みソケット2 NEW! NEW!

Slide 13

Slide 13 text

データの送受信開始 サーバー リスニングソケット クライアント1 クライアントソケット クライアント2 クライアントソケット 接続済みソケット1 接続済みソケット2 データ送受信 データ送受信

Slide 14

Slide 14 text

2. リクエストを読み取る

Slide 15

Slide 15 text

Slide 16

Slide 16 text

実際のリクエストの中⾝(⼀部省略) POST / HTTP/1.1 Host: localhost Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Content-Type: text/plain Accept: text/html,application/xhtml+xml Accept-Encoding: gzip, deflate, br, zstd Accept-Language: ja,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7,zh;q=0.6 hoge=piyo&user=h1r0

Slide 17

Slide 17 text

リクエストライン ● メソッド、リクエストター ゲット、プロトコルバージョ ンで構成される ● リクエストターゲットの形式 は 4 種類 POST / HTTP/1.1 Host: localhost Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Content-Type: text/plain Accept: text/html,application/xhtml+xml Accept-Encoding: gzip, deflate, br, zstd Accept-Language: ja,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7,zh;q=0.6 hoge=piyo&user=h1r0

Slide 18

Slide 18 text

リクエストヘッダー ● リクエストのメタデータを 設定する ● Host ヘッダーは必須であり、 存在しない場合は 400 でレス ポンスを返す必要がある ● 改⾏区切り ● クライアントが独⾃にキーを 設定することも可能 POST / HTTP/1.1 Host: localhost Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Content-Type: text/plain Accept: text/html,application/xhtml+xml Accept-Encoding: gzip, deflate, br, zstd Accept-Language: ja,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7,zh;q=0.6 hoge=piyo&user=h1r0

Slide 19

Slide 19 text

リクエストボディ ● 任意項⽬ ● プレーンテキストや JSON など形式は様々 ● Content-Length もしくは Transfer-Encoding ヘッダー で⻑さを把握する POST / HTTP/1.1 Host: localhost Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Content-Type: text/plain Accept: text/html,application/xhtml+xml Accept-Encoding: gzip, deflate, br, zstd Accept-Language: ja,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7,zh;q=0.6 hoge=piyo&user=h1r0

Slide 20

Slide 20 text

3. レスポンスを組み⽴てて返す

Slide 21

Slide 21 text

レスポンスの組み⽴て Hello!"; } } リクエスト同様、中⾝はテキス トであり、RFC で定義された構 造に沿って設定する。

Slide 22

Slide 22 text

ステータスライン ● プロトコルバージョン、ス テータスコード、ステータス コードの説明(任意項⽬)で 構成される Hello!"; … } }

Slide 23

Slide 23 text

レスポンスヘッダー ● レスポンスのメタデータを 設定する ● 必須のキーはない ● 改⾏区切り ● サーバー独⾃にキーを設定 することも可能 Hello!"; … } }

Slide 24

Slide 24 text

レスポンスボディ ● 任意項⽬ ● プレーンテキストや JSON など形式は様々 ● リクエストメソッド、ステー タスコード、Content-Length もしくはTransfer-Encoding ヘッダーで⻑さを把握する Hello!"; … } }

Slide 25

Slide 25 text

レスポンスの送信 fwrite で書き込むことでレスポ ンスとしてクライアントへ送信 される。 レスポンスの終了を明確にする ために fclose で接続を閉じる。

Slide 26

Slide 26 text

リクエストとレスポンスの違い リクエスト レスポンス リクエストラインと ステータスラインの 構造 メソッド リクエストターゲット プロトコルバージョン プロトコルバージョン ステータスコード ステータスコードの説明 必須ヘッダー Host なし ボディの⻑さを決定 するアルゴリズム Content-Length もしくは Transfer-Encoding ヘッダー リクエストメソッド ステータスコード 左記のヘッダー

Slide 27

Slide 27 text

HTTP のプロトコルバージョン 本⽇お話したのは HTTP/1.1(RFC 9112)の内容です。 現在は HTTP/2 と HTTP/3 があり、仕様が異なります。 詳細な仕様についてはそれぞれの RFC をご参照ください。 HTTP/2:RFC 9113 HTTP/3:RFC 9114

Slide 28

Slide 28 text

Web サーバーを作って感じたこと

Slide 29

Slide 29 text

⾞輪の再発明は無駄じゃない ● 20 ⾏程度の簡単なものを作ることが、理解への近道だった ○ 今⽇話した内容を理解するまでにかかった時間は、トー タル 1 週間程度 ● 仕組みを理解することで、Web サーバーの設定値に対する 理解も深まった ● 他にも⾊々作ってみたくなった ○ DB サーバー作成予定

Slide 30

Slide 30 text

まとめ ● Web サーバーの仕事は 3 ステップ ○ 待つ、読む、返す ● ソケットを使うことでクライアントとサーバーが通信できる ● HTTP/1.1 ではリクエストとレスポンスはテキストである ● 普段当たり前に使っているものを⾃作することでより理解を 深められる

Slide 31

Slide 31 text

さあ、⾞輪を再発明しよう。

Slide 32

Slide 32 text

ご清聴ありがとうございました GitHub で実際に作った web サーバー公開してます。 https://github.com/H-H1RO/php-webserver