Newer
Older
hello-programmer-world / src / pages / php / 040-work.mdx
@h.sakamoto h.sakamoto 15 hours ago 6 KB quiz
---
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の基本的な機能を使ってインタラクティブなウェブアプリケーションを作成しました。

- フォームからのデータ受け取り
- 条件分岐による処理の切り替え
- エラーハンドリング

これらはウェブアプリケーション開発の基礎となる重要な概念です。  
ぜひ自分なりにアレンジして、さまざまなクイズを作ってみてください。