summaryrefslogtreecommitdiffhomepage
path: root/slides.typ
diff options
context:
space:
mode:
Diffstat (limited to 'slides.typ')
-rw-r--r--slides.typ607
1 files changed, 607 insertions, 0 deletions
diff --git a/slides.typ b/slides.typ
new file mode 100644
index 0000000..906b1e1
--- /dev/null
+++ b/slides.typ
@@ -0,0 +1,607 @@
+#import "@preview/touying:0.6.1": *
+#import "@preview/cades:0.3.1": qr-code
+#import "@preview/codly:1.3.0": *
+#import "@preview/cjk-unbreak:0.2.0": remove-cjk-break-space, transform-childs
+#import "setoka.typ": *
+
+#show: codly-init.with()
+
+#show: remove-cjk-break-space
+
+#let plugin_tokenize_ja_uninitialized = plugin("plugins/tokenize-ja/tokenize-ja.wasm")
+#let plugin_tokenize_ja = plugin.transition(plugin_tokenize_ja_uninitialized.init)
+
+#let tokenize(s) = {
+ cbor(plugin_tokenize_ja.tokenize(bytes(s)))
+}
+
+#let get-inner-str(e) = {
+ if e.func() == text {
+ if e.has("text") {
+ e.text
+ } else if e.has("body") {
+ e.body
+ } else {
+ none
+ }
+ } else {
+ none
+ }
+}
+
+#let make-助詞-small(rest) = {
+ rest = transform-childs(rest, make-助詞-small)
+ if utils.is-sequence(rest) {
+ for child in rest.children {
+ let s = get-inner-str(child)
+ if s != none {
+ for t in tokenize(s) {
+ if t.at(1) == "助詞" {
+ [#set text(size: 0.9em);#t.at(0)]
+ } else {
+ t.at(0)
+ }
+ }
+ } else {
+ child
+ }
+ }
+ } else {
+ rest
+ }
+}
+
+#show: make-助詞-small
+
+#show: setoka-theme.with(
+ aspect-ratio: "16-9",
+ config-info(
+ title: [
+ Pure PHP で作る \
+ 簡易 HTTP サーバ
+ ],
+ subtitle: [PHP カンファレンス香川 2025],
+ author: [nsfisis (いまむら)],
+ date: datetime(year: 2025, month: 11, day: 24),
+ ),
+ config-common(preamble: {
+ codly(
+ fill: rgb("#eee"),
+ lang-format: none,
+ number-format: none,
+ zebra-fill: none,
+ )
+ })
+)
+
+#set text(font: "Noto Sans CJK JP", lang: "ja")
+
+#title-slide()
+
+#about-slide()
+
+#[
+#set align(center + horizon)
+
+Pure PHP で作る \
+簡易 HTTP サーバ
+
+]
+
+---
+
+#[
+#set text(size: 0.9em)
+
+- HTTP とは
+- サーバを実装する
+ - GET
+ - POST
+ - Cookie
+
+]
+
+---
+
+#[
+#set align(center + horizon)
+#set text(size: 2em)
+
+*HTTP*
+
+]
+
+---
+
+#strong[H]yper#strong[t]ext \
+#strong[T]ransfer \
+#strong[P]rotocol
+
+---
+
+Hypertext #pause
+
+すごいテキスト #pause
+
+Hyperlink されたテキスト
+
+---
+
+Hypertext
+
+相互に接続され、\
+容易に参照できるテキスト
+
+---
+
+Hyper でない text
+
+書籍
+
+---
+
+#strong[H]yper#strong[t]ext \
+#strong[T]ransfer \
+#strong[P]rotocol
+
+---
+
+#[
+#set text(size: 0.9em)
+
+Transfer
+
+転送
+
+コンピュータ間でデータを送る
+]
+
+---
+
+#strong[H]yper#strong[t]ext \
+#strong[T]ransfer \
+#strong[P]rotocol
+
+---
+
+Protocol #pause
+
+予め定められた \
+取り決め・手順
+
+---
+
+#[
+#set text(size: 0.7em)
+
+挨拶プロトコル #pause
+
+A「こんにちは」#pause \
+B「こんにちは」#pause
+
+相手の言葉を少し遅れて繰り返す
+
+---
+
+挨拶プロトコル
+
+A「こんにちは」#pause \
+B「かけうどん」#pause
+
+挨拶失敗 \
+プロトコルを守っていない
+
+]
+
+---
+
+#[
+#set text(size: 0.9em)
+
+#strong[H]yper#strong[t]ext \
+#strong[T]ransfer \
+#strong[P]rotocol
+
+#pause
+すごい文書を転送するための手順
+
+]
+
+---
+
+具体的な HTTP の手順
+
+#pause
+
+#[
+#set text(size: 0.7em)
+
+クライアント「`GET /index.html HTTP/1.1`」#pause \
+サーバ「`HTTP/1.1 200 OK`」
+
+#pause
+
+クライアントからのリクエストに対し \
+サーバがレスポンスを返す
+
+]
+
+---
+
+プロトコルスタック
+
+---
+
+#[
+#set text(size: 0.6em)
+
+- HTTP
+ - Hypertext Transfer Protocol #pause
+- TCP
+ - Transmission Control Protocol #pause
+- IP
+ - Internet Protocol
+- ...
+
+#pause
+TCP/IP プロトコルスタック
+
+]
+
+---
+
+プロトコルスタック
+
+下の階層・上の階層について \
+気にしなくてもよい
+
+---
+
+#[
+#set align(center + horizon)
+
+HTTP サーバを作る
+
+]
+
+---
+
+HTTP のバージョン
+
+- *HTTP/1.1*
+- HTTP/2
+- HTTP/3
+
+---
+
+#[
+#set text(size: 0.9em)
+
+HTTP/1.1
+
+#link("https://datatracker.ietf.org/doc/html/rfc9112")[RFC 9112] (など)
+
+HTTP/1.1 の具体的なプロトコルを \
+定めた標準規格
+
+---
+
+クライアントがリクエストを送る
+
+サーバがレスポンスを返す
+
+]
+
+---
+
+#[
+#set text(size: 0.7em)
+
+リクエスト
+
+- リクエスト行 + CRLF
+- 任意個数のフィールド行 + CRLF
+- CRLF
+- メッセージボディ
+
+---
+
+リクエスト行
+
+- メソッド
+ - GET、POST、...
+- リクエストターゲット
+- HTTP バージョン
+
+```
+GET /index.html HTTP/1.1
+```
+
+---
+
+フィールド行
+
+- フィールド名
+- `:`
+- フィールド値
+
+```
+Host: example.com
+```
+
+---
+
+リクエスト
+
+- リクエスト行 + CRLF
+- 任意個数のフィールド行 + CRLF
+- CRLF
+- メッセージボディ
+
+---
+
+レスポンス
+
+- ステータス行 + CRLF
+- 任意個数のフィールド行 + CRLF
+- CRLF
+- メッセージボディ
+
+---
+
+ステータス行
+
+- HTTP バージョン
+- ステータスコード
+- リーズンフレーズ (reason phrase)
+
+```
+HTTP/1.1 200 OK
+```
+
+---
+
+GET メソッドに応答する
+
+```
+GET /get/ HTTP/1.1
+```
+
+```
+HTTP/1.1 200 OK
+
+<本文>
+```
+
+]
+
+---
+
+#[
+#set text(size: 0.5em)
+#set align(center + horizon)
+
+https://t.nil.ninja/phpcon-kagawa-2025/get/
+
+#qr-code("https://t.nil.ninja/phpcon-kagawa-2025/get/", width: 9cm)
+
+]
+
+---
+
+
+#[
+#set text(size: 0.5em)
+#set align(center + horizon)
+
+#link("https://github.com/nsfisis/nil.ninja/blob/67094790d2d9db5c99e7c136f49061a78698e57d/vhosts/t/phpcon-kagawa-2025/src/Http/Server.php")[主な実装ファイル]
+
+#qr-code("https://github.com/nsfisis/nil.ninja/blob/67094790d2d9db5c99e7c136f49061a78698e57d/vhosts/t/phpcon-kagawa-2025/src/Http/Server.php", width: 9cm)
+
+]
+
+---
+
+フォームを送れるように \
+しよう
+
+---
+
+#[
+#set text(size: 0.9em)
+
+POST メソッド
+
+#pause
+プロトコルレベルでは GET と \
+ほぼ同じ
+
+]
+
+---
+
+#[
+#set text(size: 0.5em)
+#set align(center + horizon)
+
+https://t.nil.ninja/phpcon-kagawa-2025/post/
+
+#qr-code("https://t.nil.ninja/phpcon-kagawa-2025/post/", width: 9cm)
+
+]
+
+---
+
+#[
+#set text(size: 0.9em)
+
+GET・POST の違い
+
+#[
+#set text(size: 0.7em)
+
+プロトコルレベルでは\
+ほとんど同じ
+
+セマンティクス・慣例的な\
+使われ方が異なっている
+
+]
+
+]
+
+---
+
+HTTP における状態の管理
+
+---
+
+#[
+#set text(size: 0.6em)
+
+うどん店 (セルフでない)
+
+#pause
+
+- 客1「かけ」#pause
+- 店員「かけ一つ」#pause
+- 客2「釜玉」#pause
+- 店員「釜玉一つ」#pause
+- 客1「以上で」#pause
+- 店員「まだご注文頂いていません」
+
+]
+
+---
+
+やり取りのたびに記憶を失う
+
+ステートレス
+
+---
+
+解決方法
+
+- クッキー
+- セッション
+
+---
+
+#[
+#set text(size: 0.6em)
+
+クッキー
+
+#pause
+- 客1「かけ」#pause
+- 店員「かけ一つ」#pause
+- 客2「かけと釜玉」#pause
+- 店員「かけ一つと釜玉一つ」#pause
+- 客1「かけと釜玉。以上で」#pause
+- 店員「かけ一つと釜玉一つ。以上ですね」
+
+---
+
+クッキー
+
+- 客1「かけ」
+- 店員「かけ一つ」`Set-Cookie: order="かけ"`
+- 客2「かけと釜玉」`Cookie: order="かけ"`
+- 店員「かけ一つと釜玉一つ」\
+ `Set-Cookie: order="かけ,釜玉"`
+- 客1「かけと釜玉。以上で」`Cookie: order="かけ,釜玉"`
+- 店員「かけ一つと釜玉一つ。以上ですね」
+
+---
+
+セッション
+
+#pause
+- 番号札を渡す (23)#pause
+- 客1「番号23。かけ」#pause
+- 店員「かけ一つ」番号23: かけ#pause
+- 客2「番号23。釜玉」#pause
+- 店員「かけ一つと釜玉一つ」番号23: かけ,釜玉#pause
+- 客1「番号23。以上で」#pause
+- 店員「かけ一つと釜玉一つ。以上ですね」
+
+---
+
+セッション
+
+- 番号札を渡す (23)`Set-Cookie: session_id="23"`
+- 客1「番号23。かけ」`Cookie: session_id="23"`
+- 店員「かけ一つ」番号23: かけ
+- 客2「番号23。釜玉」`Cookie: session_id="23"`
+- 店員「かけ一つと釜玉一つ」番号23: かけ,釜玉
+- 客1「番号23。以上で」`Cookie: session_id="23"`
+- 店員「かけ一つと釜玉一つ。以上ですね」
+
+]
+
+---
+
+#[
+#set text(size: 0.5em)
+#set align(center + horizon)
+
+https://t.nil.ninja/phpcon-kagawa-2025/cookie/
+
+#qr-code("https://t.nil.ninja/phpcon-kagawa-2025/cookie/", width: 9cm)
+
+]
+
+---
+
+#[
+#set align(center + horizon)
+
+#[
+#set text(size: 2em)
+
+まとめ
+]
+
+---
+
+#[
+#set text(size: 2em)
+HTTP
+]
+
+---
+
+技術を理解する \
+最も確実な方法は \
+*実装*すること
+
+---
+
+HTTP は手軽に実装できる\
+プロトコル
+
+---
+
+HTTP を手軽に実装しよう
+
+---
+
+#[
+#set align(top + left)
+#set text(size: 0.7em)
+
+- PHPerKaigi 2026 (3/20-22)
+ - プロポーザル募集中
+- PHP カンファレンス小田原 2026 (4/11)
+ - プロポーザル募集開始予定
+- PHP カンファレンス愛媛 2026 (10/3)
+ - 準備中
+
+]
+
+---
+
+ご静聴 \
+ありがとうございました
+
+]