diff options
Diffstat (limited to 'vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025')
6 files changed, 411 insertions, 0 deletions
diff --git a/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/CookieEatHandler.php b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/CookieEatHandler.php new file mode 100644 index 0000000..93e9c3b --- /dev/null +++ b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/CookieEatHandler.php @@ -0,0 +1,66 @@ +<?php + +declare(strict_types=1); + +namespace Nsfisis\TinyPhpHttpd\PhpConKagawa2025; + +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Server\RequestHandlerInterface; + +final readonly class CookieEatHandler implements RequestHandlerInterface +{ + public function __construct( + private ResponseFactoryInterface $responseFactory, + private StreamFactoryInterface $streamFactory, + ) { + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + $cookies = $request->getCookieParams(); + + $orders = []; + if (isset($cookies['order']) && $cookies['order'] !== '') { + $orders = explode(',', $cookies['order']); + } + + if (count($orders) > 0) { + $orderList = '<ul>'; + foreach ($orders as $order) { + $orderList .= '<li>' . htmlspecialchars($order) . '</li>'; + } + $orderList .= '</ul>'; + $message = '<p>ごちそうさまでした。</p>'; + } else { + $orderList = ''; + $message = '<p>注文がありません。</p>'; + } + + $body = <<<HTML +<!DOCTYPE html> +<html lang="ja"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>いただきます</title> +</head> +<body> + <div class="container"> + <h1>いただきます</h1> + {$orderList} + {$message} + <a href="/phpcon-kagawa-2025/cookie/">もう一度注文する</a> + </div> +</body> +</html> +HTML; + + return $this->responseFactory->createResponse(200) + ->withHeader('Content-Type', 'text/html; charset=UTF-8') + ->withHeader('Set-Cookie', 'order=; Max-Age=0; path=/') + ->withBody($this->streamFactory->createStream($body)); + } +} diff --git a/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/CookieHandler.php b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/CookieHandler.php new file mode 100644 index 0000000..0b9f656 --- /dev/null +++ b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/CookieHandler.php @@ -0,0 +1,92 @@ +<?php + +declare(strict_types=1); + +namespace Nsfisis\TinyPhpHttpd\PhpConKagawa2025; + +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Server\RequestHandlerInterface; + +final readonly class CookieHandler implements RequestHandlerInterface +{ + public function __construct( + private ResponseFactoryInterface $responseFactory, + private StreamFactoryInterface $streamFactory, + ) { + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + $cookies = $request->getCookieParams(); + + $orders = []; + if (isset($cookies['order']) && $cookies['order'] !== '') { + $orders = explode(',', $cookies['order']); + } + + $setCookie = null; + + if ($request->getMethod() === 'POST') { + $postData = []; + parse_str((string) $request->getBody(), $postData); + $newOrder = $postData['udon'] ?? ''; + if ($newOrder !== '') { + $orders[] = $newOrder; + $setCookie = 'order=' . urlencode(implode(',', $orders)) . '; path=/'; + } + } + + $orderList = ''; + if (count($orders) > 0) { + $orderList = '<h2>現在の注文</h2><ul>'; + foreach ($orders as $order) { + $orderList .= '<li>' . htmlspecialchars($order) . '</li>'; + } + $orderList .= '</ul>'; + $orderList .= '<a href="/phpcon-kagawa-2025/cookie/eat/">食べる</a>'; + } else { + $orderList = '<p>まだ注文がありません。</p>'; + } + + $body = <<<HTML +<!DOCTYPE html> +<html lang="ja"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>うどん店</title> +</head> +<body> + <main> + <h1>うどん店</h1> + <form method="POST" action="/cookie/"> + <div> + <select name="udon"> + <option value="かけ">かけ</option> + <option value="ぶっかけ">ぶっかけ</option> + <option value="釜揚げ">釜揚げ</option> + <option value="釜玉">釜玉</option> + </select> + </div> + <button type="submit">注文</button> + </form> + {$orderList} + </main> +</body> +</html> +HTML; + + $response = $this->responseFactory->createResponse(200) + ->withHeader('Content-Type', 'text/html; charset=UTF-8') + ->withBody($this->streamFactory->createStream($body)); + + if ($setCookie !== null) { + $response = $response->withHeader('Set-Cookie', $setCookie); + } + + return $response; + } +} diff --git a/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/GetHandler.php b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/GetHandler.php new file mode 100644 index 0000000..555ef79 --- /dev/null +++ b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/GetHandler.php @@ -0,0 +1,31 @@ +<?php + +declare(strict_types=1); + +namespace Nsfisis\TinyPhpHttpd\PhpConKagawa2025; + +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Server\RequestHandlerInterface; + +final readonly class GetHandler implements RequestHandlerInterface +{ + public function __construct( + private ResponseFactoryInterface $responseFactory, + private StreamFactoryInterface $streamFactory, + ) { + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + ob_start(); + phpinfo(INFO_GENERAL | INFO_CREDITS | INFO_LICENSE); + $body = ob_get_clean(); + + return $this->responseFactory->createResponse(200) + ->withHeader('Content-Type', 'text/plain; charset=UTF-8') + ->withBody($this->streamFactory->createStream($body)); + } +} diff --git a/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/HealthHandler.php b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/HealthHandler.php new file mode 100644 index 0000000..2c2d1b5 --- /dev/null +++ b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/HealthHandler.php @@ -0,0 +1,29 @@ +<?php + +declare(strict_types=1); + +namespace Nsfisis\TinyPhpHttpd\PhpConKagawa2025; + +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Server\RequestHandlerInterface; + +final readonly class HealthHandler implements RequestHandlerInterface +{ + public function __construct( + private ResponseFactoryInterface $responseFactory, + private StreamFactoryInterface $streamFactory, + ) { + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + $body = 'OK'; + + return $this->responseFactory->createResponse(200) + ->withHeader('Content-Type', 'text/plain; charset=UTF-8') + ->withBody($this->streamFactory->createStream($body)); + } +} diff --git a/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/NotFoundHandler.php b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/NotFoundHandler.php new file mode 100644 index 0000000..0d5b33f --- /dev/null +++ b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/NotFoundHandler.php @@ -0,0 +1,29 @@ +<?php + +declare(strict_types=1); + +namespace Nsfisis\TinyPhpHttpd\PhpConKagawa2025; + +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Server\RequestHandlerInterface; + +final readonly class NotFoundHandler implements RequestHandlerInterface +{ + public function __construct( + private ResponseFactoryInterface $responseFactory, + private StreamFactoryInterface $streamFactory, + ) { + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + $body = '404 Not Found'; + + return $this->responseFactory->createResponse(404) + ->withHeader('Content-Type', 'text/plain; charset=UTF-8') + ->withBody($this->streamFactory->createStream($body)); + } +} diff --git a/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/PostHandler.php b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/PostHandler.php new file mode 100644 index 0000000..2653e3e --- /dev/null +++ b/vhosts/t/phpcon-kagawa-2025/src/PhpConKagawa2025/PostHandler.php @@ -0,0 +1,164 @@ +<?php + +declare(strict_types=1); + +namespace Nsfisis\TinyPhpHttpd\PhpConKagawa2025; + +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Server\RequestHandlerInterface; + +final readonly class PostHandler implements RequestHandlerInterface +{ + /** + * @var array<string, string> + */ + private const array ANSWERS = [ + 'ehime' => 'hiroshima', + 'kagawa' => 'okayama', + 'tokushima' => 'hyogo', + ]; + + /** + * @var array<string, string> + */ + private const array PREFECTURE_NAMES = [ + 'okayama' => '岡山', + 'hiroshima' => '広島', + 'yamaguchi' => '山口', + 'hyogo' => '兵庫', + 'osaka' => '大阪', + ]; + + private const string QUIZ_FORM = <<<'HTML' +<!DOCTYPE html> +<html lang="ja"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>本州四国連絡橋クイズ</title> +</head> +<body> + <main> + <h1>本州四国連絡橋クイズ</h1> + <p>四国の各県と橋でつながっている中国地方の県を選んでください。</p> + <form method="POST" action="/post/"> + <div> + <label>愛媛とつながっているのは?</label> + <select name="ehime"> + <option value="">選択してください</option> + <option value="okayama">岡山</option> + <option value="hiroshima">広島</option> + <option value="yamaguchi">山口</option> + <option value="hyogo">兵庫</option> + <option value="osaka">大阪</option> + </select> + </div> + <div> + <label>香川とつながっているのは?</label> + <select name="kagawa"> + <option value="">選択してください</option> + <option value="okayama">岡山</option> + <option value="hiroshima">広島</option> + <option value="yamaguchi">山口</option> + <option value="hyogo">兵庫</option> + <option value="osaka">大阪</option> + </select> + </div> + <div> + <label>徳島とつながっているのは?</label> + <select name="tokushima"> + <option value="">選択してください</option> + <option value="okayama">岡山</option> + <option value="hiroshima">広島</option> + <option value="yamaguchi">山口</option> + <option value="hyogo">兵庫</option> + <option value="osaka">大阪</option> + </select> + </div> + <button type="submit">回答する</button> + </form> + </main> +</body> +</html> +HTML; + + public function __construct( + private ResponseFactoryInterface $responseFactory, + private StreamFactoryInterface $streamFactory, + ) { + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + if ($request->getMethod() === 'POST') { + $postData = []; + parse_str((string) $request->getBody(), $postData); + + $userEhime = $postData['ehime'] ?? ''; + $userKagawa = $postData['kagawa'] ?? ''; + $userTokushima = $postData['tokushima'] ?? ''; + + $results = []; + $score = 0; + + // Ehime + $userEhimeName = self::PREFECTURE_NAMES[$userEhime] ?? $userEhime; + if ($userEhime === self::ANSWERS['ehime']) { + $results[] = '<p>愛媛: ' . htmlspecialchars($userEhimeName) . ' ⭕ 正解!</p>'; + $score++; + } else { + $results[] = '<p>愛媛: ' . htmlspecialchars($userEhimeName) . ' ❌ 不正解</p>'; + } + + // Kagawa + $userKagawaName = self::PREFECTURE_NAMES[$userKagawa] ?? $userKagawa; + if ($userKagawa === self::ANSWERS['kagawa']) { + $results[] = '<p>香川: ' . htmlspecialchars($userKagawaName) . ' ⭕ 正解!</p>'; + $score++; + } else { + $results[] = '<p>香川: ' . htmlspecialchars($userKagawaName) . ' ❌ 不正解</p>'; + } + + // Tokushima + $userTokushimaName = self::PREFECTURE_NAMES[$userTokushima] ?? $userTokushima; + if ($userTokushima === self::ANSWERS['tokushima']) { + $results[] = '<p>徳島: ' . htmlspecialchars($userTokushimaName) . ' ⭕ 正解!</p>'; + $score++; + } else { + $results[] = '<p>徳島: ' . htmlspecialchars($userTokushimaName) . ' ❌ 不正解</p>'; + } + + $resultHtml = implode("\n", $results); + + $body = <<<HTML +<!DOCTYPE html> +<html lang="ja"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>クイズ結果</title> +</head> +<body> + <main> + <h1>クイズ結果</h1> + <p class="score">スコア: {$score} / 3</p> + {$resultHtml} + <p> + <a href="/phpcon-kagawa-2025/post/">もう一度挑戦する</a> + </p> + </main> +</body> +</html> +HTML; + } else { + $body = self::QUIZ_FORM; + } + + return $this->responseFactory->createResponse(200) + ->withHeader('Content-Type', 'text/html; charset=UTF-8') + ->withBody($this->streamFactory->createStream($body)); + } +} |
