---
layout: "@/layouts/MarkdownLayout.astro"
---
import Toc from "../../components/Toc.astro";
import Details from "@/components/Details.astro";
export const title = "クイズを作ってみよう";
import DockerLink from "@/components/DockerLink.astro";
# {title}
これまで学んだPHPの知識を使って、クイズアプリを作ってみましょう。
## TOC
## 演習の目的
この演習では、以下のPHPの機能を実践的に学びます。
- フォームデータの受け取り(`$_POST`)
- 条件分岐(`if`文)
- 変数の使い方
- `htmlspecialchars()`によるセキュリティ対策
## 課題
`/workspace/php/`ディレクトリにテンプレートファイルが用意されています。
これを編集して、オリジナルのクイズを作成してください。
### 必要なファイル
- `quiz.html` - クイズ問題を表示するHTMLファイル(そのまま使えます)
- `submit.php` - 答えを判定するPHPファイル(**TODOを実装してください**)
### 実装する内容
`submit.php`には4つのTODOが書かれています。順番に実装していきましょう。
#### TODO 1: フォームから送信されたかチェックする
直接このページにアクセスされた場合にエラーを表示します。
<Details summary="ヒント1: どうやってチェックする?">
`$_SERVER["REQUEST_METHOD"]`という特別な変数を使います。
フォームが`method="post"`で送信された場合、この値は`"POST"`になります。
</Details>
<Details summary="ヒント2: サンプルコード">
```php
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
echo '<h1>エラー</h1>';
echo '<p>不正なアクセスです。</p>';
exit; // ここで処理を終了
}
```
`!==`は「等しくない」という意味です。POSTメソッド以外でアクセスされた場合はエラーを表示して終了します。
</Details>
#### TODO 2: 送信された答えを取得する
フォームから送信されたユーザーの答えを変数に保存します。
<Details summary="ヒント1: どうやって取得する?">
`$_POST`という特別な配列を使います。
`quiz.html`のinputタグの`name="answer"`に対応して、`$_POST["answer"]`で値を取得できます。
</Details>
<Details summary="ヒント2: サンプルコード">
```php
$userAnswer = $_POST["answer"] ?? "";
```
`??`は「左側の値が存在しない場合は右側の値を使う」という意味です。
これにより、値が送信されなかった場合でもエラーにならず、空文字列が入ります。
</Details>
#### TODO 3: 正解を設定する
正解の値を変数に保存します。
<Details summary="ヒント1: どの値を設定する?">
`quiz.html`の正解の選択肢の`value`属性の値を設定します。
例えば、`<input type="radio" name="answer" value="option1">`が正解なら`"option1"`です。
</Details>
<Details summary="ヒント2: サンプルコード">
```php
$correctAnswer = "option1";
```
もちろん、`quiz.html`を編集して問題を変更した場合は、それに合わせて変更してください。
</Details>
#### TODO 4: 正誤判定をする
ユーザーの答えと正解を比較して、結果を表示します。
<Details summary="ヒント1: どうやって比較する?">
`if`文を使って、`$userAnswer`と`$correctAnswer`が等しいかをチェックします。
等しい場合は正解、そうでない場合は不正解のメッセージを表示します。
</Details>
<Details summary="ヒント2: サンプルコード">
```php
if ($userAnswer === $correctAnswer) {
echo '<h1>正解です!</h1>';
echo '<p>よくできました。</p>';
} else {
echo '<h1>不正解です</h1>';
echo '<p>残念!もう一度考えてみましょう。</p>';
}
```
`===`は「完全に等しい」という意味です。メッセージの内容は自由に変更できます。
</Details>
## quiz.htmlの編集
`quiz.html`は問題文と選択肢を自由に編集できます。
```html
<!-- 問題文を自由に変更できます -->
<p>問題: ここに問題を書きましょう</p>
<!-- 選択肢は何個でも追加できます -->
<label>
<input type="radio" name="answer" value="option1" required>
選択肢1
</label>
```
**重要なポイント:**
- `value`属性の値が`submit.php`に送信されます
- `name`属性は全ての選択肢で同じ(`"answer"`)にする必要があります
- 正解の選択肢の`value`を覚えておいて、`submit.php`のTODO 3で使います
## 発展課題
基本的なクイズができたら、以下の機能を追加してみましょう。
### 1. スタイルを追加する
`quiz.html`と`submit.php`にCSSを追加して、見た目を良くしてみましょう。
```html
<style>
body {
font-family: sans-serif;
max-width: 600px;
margin: 50px auto;
padding: 20px;
}
/* 他のスタイルを追加 */
</style>
```
### 2. 複数の問題に対応する
配列を使って複数の問題を管理してみましょう。
```php
// quiz.phpとして作成
<?php
$questions = [
[
"question" => "問題1",
"options" => ["選択肢1", "選択肢2", "選択肢3"],
"answer" => "選択肢1"
],
// 問題を追加
];
// ランダムに1問選ぶ
$randomIndex = array_rand($questions);
$selectedQuestion = $questions[$randomIndex];
?>
```
### 3. 解説を追加する
不正解の場合に、なぜその答えが正解なのかを説明する機能を追加してみましょう。
```php
if ($userAnswer === $correctAnswer) {
echo '<h1>正解です!</h1>';
echo '<p>解説: 正解の理由を書きます</p>';
} else {
echo '<h1>不正解です</h1>';
echo '<p>解説: 不正解の理由と正しい知識を書きます</p>';
}
```
## 確認方法
作成したクイズは以下の方法で確認できます。
<DockerLink href="workspace/php/quiz.html" />
1. リンクをクリックしてクイズページを開く
2. 問題を読んで答えを選択する
3. 「答えを送信」ボタンをクリック
4. 正誤判定の結果が表示されることを確認する
## まとめ
この演習では、PHPの基本的な機能を使ってインタラクティブなウェブアプリケーションを作成しました。
- フォームからのデータ受け取り
- 条件分岐による処理の切り替え
- エラーハンドリング
これらはウェブアプリケーション開発の基礎となる重要な概念です。
ぜひ自分なりにアレンジして、さまざまなクイズを作ってみてください。