PHPで診断テストプログラムの作り方【サンプルコードで解説】

2020年2月6日

PHPでお手軽に診断テストを作る方法について解説します。

サイト内に診断テストを設けることで、ユーザーの入力内容から目的のものを案内したり、欲しい情報を表示させたりすることが出来ます。

そんな、今回作る診断テストプログラムの概要はこちら。

  1. 4択の選択肢を5問表示させる
    選択肢ごとに点数を設ける
  2. すべて選択を終えたらボタンを押し、別ページに遷移
  3. 別ページ先にて、選択した点数の合計で、表示を変える

入力ページと結果ページで分けますので、ご一緒に開発される方は2つのPHPファイルを用意しておいてください。
今回の解説で使用するファイル名はこちら。

  • shindan_input.php(診断テスト入力ページ)
  • shindan_result.php(診断結果表示ページ)

この2つのPHPファイルを使用して、とてもシンプルですが、汎用的に使いまわせるような形で作っていきたいと思います。

また、名称を変えればそのまま「クイズ」のようなコンテンツにも応用が出来ます。

まずは診断テスト完成例をご確認ください。

まずはサンプルとして、簡単に「リア充診断テスト」を作ってみました。

リア充寄りの回答をするとそれっぽいメッセージが、そうでない場合は慰めのメッセージが別ページで表示されます。

あくまでサンプルであり、診断結果には何の意味もないので、結果を深く考えないでください。(10秒くらいで考えました)


1.妻・夫、または彼女・彼氏がいる?

2.あなたのLINEの友達の人数は?

3.週ごとに友達とは何日会う?

4.年賀状は何枚届いた?

5.あけおめLINEが届いた人数は?


診断テストプログラムの作り方

shindan_input.php(入力画面)を作る

まずは、入力画面となるshindan_input.phpを作っていきましょう。

【shindan_input.php】問題文を設定した配列を作る

各5問、かつ4択を設定した配列変数をPHPで作りましょう。

手動ですべて書いても良いですが、手入力の量が増えて修正が大変になるので、配列を使用してHTMLに表示させる方法が楽です。

$aryShindan = [];

$cnt = 1;
$aryShindan[$cnt]['question'] = '妻・夫、または彼女・彼氏がいる?';
$aryShindan[$cnt]['answer'][] = ['point' => 4, 'text' => 'いる'];
$aryShindan[$cnt]['answer'][] = ['point' => 3, 'text' => 'いたけど1年以内に分かれた'];
$aryShindan[$cnt]['answer'][] = ['point' => 2, 'text' => 'いたけど5年以内に分かれた'];
$aryShindan[$cnt]['answer'][] = ['point' => 1, 'text' => 'いない歴=年齢'];

$cnt = 2;
$aryShindan[$cnt]['question'] = 'あなたのLINEの友達の人数は?';
$aryShindan[$cnt]['answer'][] = ['point' => 4, 'text' => '100人以上'];
$aryShindan[$cnt]['answer'][] = ['point' => 3, 'text' => '30~99人'];
$aryShindan[$cnt]['answer'][] = ['point' => 2, 'text' => '10~29人'];
$aryShindan[$cnt]['answer'][] = ['point' => 1, 'text' => '9人以下'];

$cnt = 3;
$aryShindan[$cnt]['question'] = '週ごとに友達とは何日会う?';
$aryShindan[$cnt]['answer'][] = ['point' => 4, 'text' => '3日以上'];
$aryShindan[$cnt]['answer'][] = ['point' => 3, 'text' => '2日'];
$aryShindan[$cnt]['answer'][] = ['point' => 2, 'text' => '1日'];
$aryShindan[$cnt]['answer'][] = ['point' => 1, 'text' => '1回も合わない日が多い'];

$cnt = 4;
$aryShindan[$cnt]['question'] = '年賀状は何枚届いた?';
$aryShindan[$cnt]['answer'][] = ['point' => 4, 'text' => '20枚以上'];
$aryShindan[$cnt]['answer'][] = ['point' => 3, 'text' => '10~19枚'];
$aryShindan[$cnt]['answer'][] = ['point' => 2, 'text' => '5~9枚'];
$aryShindan[$cnt]['answer'][] = ['point' => 1, 'text' => '4枚以下'];

$cnt = 5;
$aryShindan[$cnt]['question'] = 'あけおめLINEが届いた人数は?';
$aryShindan[$cnt]['answer'][] = ['point' => 4, 'text' => '20人以上'];
$aryShindan[$cnt]['answer'][] = ['point' => 3, 'text' => '10~19人'];
$aryShindan[$cnt]['answer'][] = ['point' => 2, 'text' => '5~9人'];
$aryShindan[$cnt]['answer'][] = ['point' => 1, 'text' => '4人以下'];

問題数ごとに、questionに出題文を、answerには回答文とポイントを設定しております。

配列の構造が理解しやすいと思うので、print_r()で展開した形もご確認ください。

Array
(
    [1] => Array
        (
            [question] => 妻・夫、または彼女・彼氏がいる?
            [answer] => Array
                (
                    [0] => Array
                        (
                            [point] => 4
                            [text] => いる
                        )
                    [1] => Array
                        (
                            [point] => 3
                            [text] => いたけど1年以内に分かれた
                        )
                    [2] => Array
                        (
                            [point] => 2
                            [text] => いたけど5年以内に分かれた
                        )
                    [3] => Array
                        (
                            [point] => 1
                            [text] => いない歴=年齢
                        )
                )
        )
    [2] => Array
        (
            [question] => あなたのLINEの友達の人数は?
            [answer] => Array
                (
                    [0] => Array
                        (
                            [point] => 4
                            [text] => 100人以上
                        )
                    [1] => Array
                        (
                            [point] => 3
                            [text] => 30~99人
                        )
                    [2] => Array
                        (
                            [point] => 2
                            [text] => 10~29人
                        )
                    [3] => Array
                        (
                            [point] => 1
                            [text] => 9人以下
                        )
                )
        )
    [3] => Array
        (
            [question] => 週ごとに友達とは何日会う?
            [answer] => Array
                (
                    [0] => Array
                        (
                            [point] => 4
                            [text] => 3日以上
                        )
                    [1] => Array
                        (
                            [point] => 3
                            [text] => 2日
                        )
                    [2] => Array
                        (
                            [point] => 2
                            [text] => 1日
                        )
                    [3] => Array
                        (
                            [point] => 1
                            [text] => 1回も合わない日が多い
                        )
                )
        )
    [4] => Array
        (
            [question] => 年賀状は何枚届いた?
            [answer] => Array
                (
                    [0] => Array
                        (
                            [point] => 4
                            [text] => 20枚以上
                        )
                    [1] => Array
                        (
                            [point] => 3
                            [text] => 10~19枚
                        )
                    [2] => Array
                        (
                            [point] => 2
                            [text] => 5~9枚
                        )
                    [3] => Array
                        (
                            [point] => 1
                            [text] => 4枚以下
                        )
                )
        )
    [5] => Array
        (
            [question] => あけおめLINEが届いた人数は?
            [answer] => Array
                (
                    [0] => Array
                        (
                            [point] => 4
                            [text] => 20人以上
                        )
                    [1] => Array
                        (
                            [point] => 3
                            [text] => 10~19人
                        )
                    [2] => Array
                        (
                            [point] => 2
                            [text] => 5~9人
                        )
                    [3] => Array
                        (
                            [point] => 1
                            [text] => 4人以下
                        )
                )
        )
)

設定した配列をforeachで回してHTMLを生成する

先ほど設定した配列を、foreachの繰り返し処理で回して、HTMLタグを打ち込んでいきます。

参考 PHPのforeachを徹底解説【サンプルコード有】

回答となる選択肢は、フォームタグのラジオボタンを使用します。

<form method="post" action="shindan_result.php">
<?php foreach($aryShindan as $key1 => $val1){ ?>
	<!-- タイトル -->
	<p style="font-weight:bold;"><?php echo $key1.'.'.$val1['question'] ?></p>
	<?php foreach($val1['answer'] as $key2 => $val2){ ?>
	<!-- 選択肢のループ -->
	<div><label><input required type="radio" name="shindan<?php echo $key1 ?>" value="<?php echo $val2['point'] ?>"> <?php echo $val2['text'] ?></label></div>
	<?php } ?>
<?php } ?>
	<input class="bold" type="submit" value="回答する">
</form>

文字をクリック(タップ)してもチェックできるように、ラジオボタン全体をlabelタグで囲いました。

また、回答しないとフォームが作動しないように、ラジオボタンのinput属性に「required」を付けました。
ただしこれはブラウザによって挙動が異なるため、厳密に判定を行う場合はJavaScriptなどで処理したほうが良いかもしれません。

shindan_input.php(結果画面)を作る

届いた内容の集計とテキスト表示を行おう

入力画面が正しく動いた場合、ラジオボタンで選択された内容はshindan_result.phpに送信されます。

フォーム内で、ラジオボタンで選択された値は$_POSTという配列に受け渡されます。

【PHP】$_POST配列のフォーム毎の取得方法まとめ

実際に送信すると、$_POSTの中身はこんな感じ。

サンプルコード
print_r($_POST);
Array
(
    [shidan1] => 4
    [shidan2] => 2
    [shidan3] => 3
    [shidan4] => 4
    [shidan5] => 1
)

この合計値を見て、判定を行っていきましょう。

診断用に送信した配列のキーは「shindan」という命名がありますので、キーに「shindan」が含まれる値を集計します。

その後、合計値を見て、診断テストの判定を行います。

$point = 0;
foreach($_POST as $key => $value){
    //shindanという文字が含まれるキーだったら集計する
    if(strpos($key, 'shindan') !== false){
        $point += $value;
    }
}

//合計数値ごとにテキスト表示を変える
$result_text = '';
if($point == 20){
    $result_text = 'すごい!あなたはスーパーリア充だ!';
}elseif($point >= 15){
    $result_text = '十分なリア充!爆発しろ!';
}elseif($point >= 10){
    $result_text = 'ややリア充!略してやや充!';
}elseif($point >= 5){
    $result_text = 'リア充の一歩手前!';
}else{
    $result_text = 'リア充力が足りない!でも幸せならいいかも!';
}

//テキストを表示 HTMLのどっかに入れてもOK
echo '<span class="font-s12 bold">'.$point.'点!'.$result_text.'</span>';

選んだ選択肢の合計値を$pointに集計し、その後if文で$pointの合計ごとにテキストを用意しておきます。

テキストは$result_textという変数に代入してあるので、あとは好きな箇所にechoして表示させてあげれば完成です。

また、「結果の内容に応じて別ページに遷移させたい」という場合は、PHPのheader関数を使うことで対応可能です。

if($point == 20){
    header('location: 20点の時のURL');
}elseif($point >= 15){
    header('location: 15~19点の時のURL');
}elseif($point >= 10){
    header('location: 10~14点の時のURL');
}elseif($point >= 5){
    header('location: 9~5点の時のURL');
}else{
    header('location: 4点の時のURL');
}
exit;

PHPで簡単に診断テストの作り方を解説してみました。

ユーザー入力内容に応じて、潜在的に求めているものを表示させてあげることが出来たら幸いです。

以上、PHPで診断テストプログラムの作り方、でした。

PHP