PHP実践_クイズUXの再現テスト→クイズ完成!

スタートから結果表示までを一続きで再現する練習

同一ページでのボタン押し下げ→再読み込み(❷)で変数がリセットされるので、現在の問題数はセッションで保持しないといけない

スポンサーリンク

プログラムの流れを計画する

❶スタート画面(start.php)

概要

フォーム<form method=”post” action=”main.php”>で問題数や難易度を選ばせる画面

セッションスタート←session_start();
セッションを消去←session_destroy();

標準的な選択肢を予め選んでおく(ラジオボタンのinputタグ内に「checked=”checked”」を入れておく)
「スタート」ボタンが押されたら、問題数($numA)や難易度($lvl)を$POST[]で➁(main.php)に引き渡しつつ、遷移する。

コード

<!DOCTYPE HTML>
<html lang=”ja”>
<head>
<meta charset=”utf-8″>
<title>クイズの全体構成作成中</title>
<link rel=”stylesheet” type=”text/css” href=”style.css”>
</head>
<body>
<?php

//データの初期化
session_start();
//session_destroy();//強制リセット

//セッションに名前があれば継続、なければ初期設定
$name=(isset($_SESSION[“name”]))? $_SESSION[“name”]:”そうちゃ”;

//セッションに得点記録があればそのまま、なければ空の配列
$_SESSION[“scoreR”]=(isset($_SESSION[“scoreR”]))? $_SESSION[“scoreR”]:[];
//継続データ(得点記録)が5件を超えたら5件のみスライス
$_SESSION[“scoreR”]=(count($_SESSION[“scoreR”])>5)? array_slice($_SESSION[“scoreR”],0,5):$_SESSION[“scoreR”];
//得点記録を一時保管
$scoreR=$_SESSION[“scoreR”];

//セッションにポイントがあればそのまま、なければ初期設定
$_SESSION[“point”]=(isset($_SESSION[“point”]))? $_SESSION[“point”]:0;
//ポイントを一時保管
$point=$_SESSION[“point”];

//セッションのリセット
session_unset();
//個別のセッション変数削除は大変…
//unset($_SESSION[‘numR’]);
//unset($_SESSION[‘numA’]);
//unset($_SESSION[‘lvl’]);
//unset($_SESSION[‘qst’]);
//unset($_SESSION[‘opt’]);
//unset($_SESSION[‘xpl’]);
//unset($_SESSION[‘ansR’]);
//unset($_SESSION[‘ansU’]);
//unset($_SESSION[‘tof’]);
//unset($_SESSION[‘msg’]);

//継続データの引き継ぎ
$_SESSION[“scoreR”]=$scoreR;
//$_SESSION[“point”]=$point;

$title=”Trial”;
$_SESSION[“title”]=$title;

//レベルと問題数の選択肢
$optLv=[“やさしい”,”ふつう”,”むずかしい”];
$optGen=[“算数”,”いろいろ”,”いろいろ(小4)”];
$optNum=[3,4,5];

//デバッグ用
//echo'<pre>第二チェック(得点記録セ、得点記録)<br>’;
//echo'<br>問題カウンターは’.$_SESSION[“numR”].'<br>’;
//var_dump($_SESSION[“title”]);
//var_dump($_SESSION[“scoreR”]);
//var_dump($scoreR);
//var_dump($_SESSION[“point”]);
//echo'</pre>’;

?>

<!– 全体枠 –>
<div class=”X-box”>

<!–タイトル表示–>
<div class=”title”><?=$title?>クイズ</div>

<!– メッセージ・ステータス表示エリア –>
<div class=”sts-msg-area” style=”height:12em;”>
<p>そうちゃ式クイズへようこそ♪「あなたの名前」を入力して、「問題のレベル」と「問題数」を選んで下さい。</p>
<p>「スタート!」ボタンを押すとクイズが始まります</p>
</div>

<!– 入力エリアここから –>
<form class=”ipt-area1″ method=”post” action=”main.php” >
<!– 名前選択 –>
<div style=”position:relative;display:inline-block;border:solid 3px lightblue;padding:1em 0.7em 0.7em;border-radius:0.5em;margin:1em 0.5em 0;vertical-align:top;”>
<div style=”vertical-align:middle;position:absolute;top:-0.8em;left:0.5em;background:#fff;font-weight:bold;padding:0 0.2em;”>なまえ</div>
<input type=”text” name=”name” value=”<?=$name?>” size=8></div>
<!– 問題数選択 –>
<div style=”position:relative;display:inline-block;border:solid 3px lightblue;padding:1em 1em 0.5em 0.5em;border-radius:0.5em;margin:1em 0.5em 0em;vertical-align:top;”>
<div style=”position:absolute;top:-0.8em;left:0.5em;background:#fff;font-weight:bold;padding:0 0.2em;”>問題数</div>
<input type=”radio” name=<?=”numA”?> value=”<?=$optNum[0]?>” ><?=$optNum[0]?>
<input type=”radio” name=<?=”numA”?> value=”<?=$optNum[1]?>” checked ><?=$optNum[1]?>
<input type=”radio” name=<?=”numA”?> value=”<?=$optNum[2]?>”><?=$optNum[2]?><br>
</div>
<br>
<!– ジャンル選択 –>
<!– ボックス –><div style=”/*opacity:0.5;*/position:relative;display:inline-block;border:solid 3px lightblue;padding:1em 1em 0.5em 0.5em;border-radius:0.5em;margin:1em auto 1em;text-align:left;”>
<!– ボックスタイトル –><div style=”position:absolute;top:-0.8em;left:0.5em;background:#fff;font-weight:bold;padding:0 0.2em;”>ジャンル</div>
<?php
$checked=”checked”;
for($i=0;$i<count($optGen);$i++){
?>
<input type=”radio” name=”gen” value=”<?=$optGen[$i]?>” <?=$checked?> ><?=$optGen[$i]?>
<?php
$checked=””;//はじめのラジオにチェックを入れたら$chekedは空白に
}
?>
</div>
<br>
<input class=”S-btn” type=”submit” value=”スタート!” >
</form>
<!– 入力エリアここまで –>
</body>
</html>

❷メイン画面(main.php)

概要・流れ

~クイズの問題と正誤を表示する画面。

(1)事前の準備
問題のデータ(問題文、解説、選択肢1(正解)、選択肢2、選択肢3…)はこのファイル(main.php)に配列($qstC[1][0]~[小問数][バリエーション数])の形で記しておく。または読み込む。

session_start();//セッション開始

(2)初期設定(カウンター変数が無い場合のみ処理)
カウンターの変数(実施中の問題数:$_SESSION[‘numR’])が無ければ「if(!isset($_SESSION[‘numR’])」、
0をセット「$_SESSION[‘numR’]=0;」
$_SESSION[‘numA’]=$_POST[‘numA’];//全問題数をセッションに
$_SESSION[‘lvl’]=$_POST[‘lvl’];//レベルをセッションに

さらに、出題する全問題を作成
$_SESSION[‘lvl’]と$_SESSION[‘numA’]から(ランダムに)問題を選んでforループで配列($_SESSION[‘qst’][0]から$_SESSION[‘qst’][$numAll-1]の[0]から[4])に格納(選択肢3つの場合)。また問題数に応じた配点も決定し$_SESSION[‘alt’][0]~[小問数]に格納しておく。

(3)通常の処理1
問題と選択肢の表示処理
カウンターに応じた問題配列($qst[$numRun])から問題文($qst[$numRun][0])を取得して$qstTに、正答($qst[$numRun][2])を取得して$ansRに代入、選択肢($_SESSION[“qst”][$numR][2]~[4])を表示用の配列($_SESSION[“opt”][$numR][0]~[2])に格納してシャッフル(shuffle($_SESSION[“opt”][$numR]))の後、フォーム<form method=”post” action=”main.php”>で問題文$SESSION[$qst][$numRun][0])とラジオボタン表示で選択肢$SESSION[”opt”][$numRun][0]~[2]と「答える」ボタン(submit)を一緒に表示。

「答える」ボタンはユーザー回答が存在しない場合のみ表示←if(!isset($_SESSION[“ansU”][numR])){}でくくる。

(5)正誤表示処理
ラジオが選択された状態で「答える」ボタンが押されてページ自身に回答($_SESSION[“ansU”][numRun])が送られていると、以下の正誤表示処理がされ、なければスキップ(表示されない)←if(isset($_SESSION[“ansU”][numRun])){}でくくる

$_SESSION[“ansU”][numRun]==$_SESSION[“qst”][numR][2](正解)なら正誤結果の配列$_SESSION[tof][$numR]に正解のフラグを入れる←$_SESSION[tof][$numR]=”T”、不正解なら不正解のフラグ”F”セット。どちらの場合でも解説$SESSION[“qst”][$numR][1]を表示して、問題のカウンター$_SESSION[$numR]を1すすめる←「$_SESSION[“numR”]++;
さらに、フォームで$_SESSION[“numA”]==$_ SESSION[“NumR”]のときだけ「次の問題へ」ボタンを表示
←if(){}で囲む

(6)最終結果への遷移ボタン表示~(5)の中の条件処理
カウンター$_SESSION[“numR”]が問題数$_SESSION[“numA”]と等しい時は、「総合結果を見る」ボタンを表示。等しくない(小さい)時はスキップ

コード

<!DOCTYPE HTML>
<html lang=”ja”>
<head>
<meta charset=”utf-8″>
<title>クイズの全体構成作成中</title>

<link rel=”stylesheet” type=”text/css” href=”style.css”>
</head>
<body>
<?php
session_start();

//正誤メッセージデータ
$_SESSION[“msg”][0]=[“正解”];//正解
$_SESSION[“msg”][1]=[“不正解”];//不正解

//配点データ(将来的には外部関数に)
$alt[3]=[30,30,40];
$alt[4]=[20,20,30,30];
$alt[5]=[15,15,20,20,30];
$alt[6]=[15,15,15,15,20,20];
$alt[7]=[10,10,10,15,15,20,20];
$alt[8]=[10,10,10,10,15,15,15,15];
$alt[10]=[5,5,5,5,10,10,10,15,15,20];

//初期設定節(問題カウンターが存在しない場合)
if(!isset($_SESSION[“numR”])){
//問題カウンターの初期値は0
$_SESSION[“numR”]=0;
//前ページ(start.php)からの受け取り
$_SESSION[“numA”]=$_POST[“numA”];//問題数$numA
$_SESSION[“gen”]=$_POST[“gen”];//
//$_SESSION[“lvl”]=$_POST[“lvl”];//レベル(未実装)
$_SESSION[“name”]=$_POST[“name”];//名前

//問題データ読み込み
include(‘qstC_nana_’.$_SESSION[“gen”].’.php’);

//問題(“qst”)のセッションへの格納
//複数の問題候補からランダムに小問を決定
for($i=0;$i<$_SESSION[“numA”];$i++){
$_SESSION[“qst”][$i]=$qstC[$i][mt_rand(0,count($qstC[$i])-1)];
}

//正解肢(“ansR”)のセッションへの格納
for($i=0;$i<$_SESSION[“numA”];$i++){
$_SESSION[“ansR”][$i]=$_SESSION[“qst”][$i][2];
}

//選択肢(“opt”)のセッションへの格納
for($i=0;$i<$_SESSION[“numA”];$i++){
for($j=0;$j<count($_SESSION[“qst”][$i])-2;$j++){
$_SESSION[“opt”][$i][$j]=$_SESSION[“qst”][$i][$j+2];
}
}

//選択肢のシャッフル(成功確認)
for($i=0;$i<$_SESSION[“numA”];$i++){
shuffle($_SESSION[“opt”][$i]);
}

//解説(“xpl”)のセッションへの格納
for($i=0;$i<$_SESSION[“numA”];$i++){
$_SESSION[“xpl”][$i]=$_SESSION[“qst”][$i][1];
}

//配点(“alt”)のセッションへの格納
//現在は問題数に合わせた一通り
$_SESSION[“alt”]=$alt[$_SESSION[“numA”]];

}//初期設定の節ここまで

//よく使う長いセッション(現在の問題数)をローカル変数に代入
$numR=$_SESSION[“numR”];

//自身からの回答受け取り節
if(isset($_POST[“ansU”])){
$_SESSION[“ansU”][$numR]=$_POST[“ansU”];
}//回答受け取り節ここまで

//デバッグ用
echo'<pre>numA’;
var_dump($_SESSION[“numA”]);
//var_dump($_SESSION[“lvl”]);
//var_dump($_SESSION[“qstC”]);
//echo'<br>問題カウンターは’.$_SESSION[“numR”].'<br>’;

//var_dump($_SESSION[“ansU”][$_SESSION[“numR”]]);
//var_dump($_SESSION[“qst”]);
//var_dump($_SESSION[“opt”]);
//var_dump($_SESSION[“title”]);
//var_dump($_SESSION[“bgCol”]);
//var_dump($_SESSION[“alt”]);
//var_dump($_SESSION[“scoreR”]);
echo'</pre>’;

?>

<!– 外枠とクイズのタイトル表示 –>
<div class=”X-box”>
<div class=”title”><?=$_SESSION[“title”]?>クイズ</div>

<!– メッセージとステータス表示エリア –>
<div class=”sts-msg-area” >

<!– 問題文は常に表示 –>
<div class=”qst-title”>
<span style=”font-size:0.75em;”>第<?=$numR+1?>問:</span><br>
<?=$_SESSION[“qst”][$numR][0]?></div>

<?php
//選択肢と回答ボタン表示節(回答がない場合のみ)
if(!isset($_SESSION[“ansU”][$numR])):
?>

<p style=”text-align:center;”>選択肢を1つ選んでボタンを押して下さい</p>
</div><!– ステータスメッセージエリアここまで –>

<!– 入力エリア表示 –>
<div class=”ipt-area2″>

<?php
//選択肢の表示(ループ)…ボタンごとに独立したフォームにしている
for($i=0;$i<count($_SESSION[“opt”][$numR]);$i++){
?>
<form method=”post” style=”/*display: inline-block;*/margin:0.2em 0″>
<input type=”hidden” name=”ansU” value=”<?=$_SESSION[“opt”][$numR][$i]?>”>
<input type=”submit” class=”A-btn” value=”<?=$i+1?>: <?=$_SESSION[“opt”][$numR][$i]?>” >
</form>
<?php
}//ループここまで
?>
</div><!– 入力エリアここまで –>
<?php
endif;//選択肢と回答ボタン表示の節ここまで
?>

<?php
//小問結果表示節(回答があった時のみ)
if(isset($_SESSION[“ansU”][$numR])):
?>
<!– 回答と正答を表示 –>
<?=$_SESSION[“name”]?><span style=”font-size:0.8em;”>さん</span>の回答:<?=$_SESSION[“ansU”][$numR]?>
正解:<?=$_SESSION[“ansR”][$numR]?>

<?php
//正誤判定処理小節(!!メッセージエリアの前におくべき!!)
if($_SESSION[“ansU”][$numR]==$_SESSION[“ansR”][$numR]){
//正解処理
$msg=$_SESSION[“msg”][0][mt_rand(0,count($_SESSION[“msg”][0])-1)];
$_SESSION[“tof”][$numR]=”T”;
}else{
//不正解処理
$msg=$_SESSION[“msg”][1][mt_rand(0,count($_SESSION[“msg”][0])-1)];
$_SESSION[“tof”][$numR]=”F”;
}//正誤判定処理小節ここまで

$_SESSION[“numR”]++;//問題カウンターを進める(代入した変数はそのままなので、この後ろは使い分ける)
?>

<!– 正誤判定表示 –>
<div class=”qst-result”><?=$msg?></div>
<div class=”xpl”>解説:<br><?=$_SESSION[“xpl”][$numR]?></div>
<?php
//次のアクションボタンの選択小節
if($_SESSION[“numR”]==$_SESSION[“numA”]){//カウンターが最終に達した場合
?>

<p>クイズは全問終了しました。ボタンを押して成績を見て下さい</p>
</div><!– ステータス・メッセージエリアここまで –>
<!– 入力エリア(最終)ここから –>
<form class=”ipt-area2″ method=”post” action=”result.php”>
<input class=”N-btn” type=”submit” value=”成績を見る”>
</form><!–入力エリア(最終)ここまで–>
<?php
}else{//カウンターが最終に達しない場合
?>
<p>残り<?=$_SESSION[“numA”]-$_SESSION[“numR”]?>問です。ボタンを押して次のクイズへ進んで下さい。</p>
</div><!– ステータス・メッセージエリアここまで –>
<!– 入力エリア(最終)ここから –>
<form class=”ipt-area2″ method=”post”>
<input class=”N-btn” type=”submit” value=”次の問題へ”>
</form><!–入力エリア(最終)ここまで–>
<?php
};//アクションボタン選択小節ここまで

endif;//小問結果表示節ここまで

//デバッグ用
//echo'<br>カウンターは’.$_SESSION[“numR”];
//var_dump($_SESSION[“tof”]);
?>
</div>

</body>
</html>

❸結果表示(result.php)

概要と流れ

~総合得点を表示する
(1)準備
このページ(result.php)内で評価の文言を配列$evl[0]~[任意の段階]に格納しておく

(2)結果など表示
$_SESSION[“tof”][0~問題数-1](正誤)と$SESSION[“$alt(配点)”]を使って正答率($_SESSION[“rate”])と点数(SESSION[$score])を表示。

正答率により段階分けした評価を表示「if($_SESSION[rate]=100
{
~;
}elseif($_SESSION[rate]>90){
$msg=”大変よくできました”~;
}elseif($_SESSION[rate]>70){
$msg=”よく出来ました。
}elseif($_SESSION[rate]>70){
$msg=”よく出来ました。
}elseif($_SESSION[rate]>70){
$msg=”よく出来ました。
}
echo:$msg;

フォーム<action=”start.php”>で「もう一回挑戦する」ボタンを表示。

コード

<!DOCTYPE HTML>
<html lang=”ja”>
<head>
<meta charset=”utf-8″>
<title>クイズの全体構成作成中</title>
<link rel=”stylesheet” type=”text/css” href=”style.css”>
</head>
<body>
<?php
session_start();

//初期設定
$mark=0;//正解数
$score=0;//得点
//$_SESSION[“tof”]に正誤(“T”か”F”)が格納済み
//$_SESSION[“alt”]に配点を格納済み

//正解のカウントと得点集計節
for($i=0;$i<count($_SESSION[“tof”]);$i++){
if($_SESSION[“tof”][$i]==”T”){//配列要素が”T”ならば
$mark++;//正答数を1プラス
$score+=$_SESSION[“alt”][$i];//配点分をプラス
}
}//正解カウントと得点集計節ここまで

array_unshift($_SESSION[“scoreR”],$score);//得点記録の最初に今回の得点を追加
$accRate=round($mark/$_SESSION[“numA”]*100);//正答率
require_once(‘funcMsgSel.php’);
$msg=msgSelect($accRate);//評価メッセージ取得

//echo'<pre>チェック(得点と得点記録)<br>’;
//var_dump($score);
//var_dump($_SESSION[“scoreR”]);
//echo'</pre>’;
?>

<!– 外枠とクイズのタイトル表示 –>
<div class=”X-box”>
<div class=”title”><?=$_SESSION[“title”]?>クイズ</div>
<!– ここからメッセージエリア –>
<div class=”sts-msg-area”>
<div class=”qst-title”><?=$_SESSION[“name”]?><span style=”font-size:0.8em;”>さん</span>の成績</div>
<p><?=$_SESSION[“numA”]?>問中<?=$mark?>問正解
(正答率<?=$accRate?>%)</p>
<p>得点は100点満点中<?=$score?>点です!</p>
<p><?=$msg?></p>
</div><!– メッセージエリアここまで –>

<form class=”ipt-area2″ method=”post” action=”start.php”>
<input class=”N-btn” type=”submit” value=”もう一回挑戦する!” >
</form>

</body>
</html>

結果

なんとか動いた。

選択肢のシャッフルなども実装。評価の文言のみ未実装

次の課題

全体の体裁を整える。htmlの字の大きさとか

見やすいクイズのレイアウトデザインを調べる考える

レイアウトの実装(スタイルシート)

データの作成(スプレッドシートからできるだけ簡単にインポート)

クイズの実装(2019.11)

一応、動くようになった。コレ

実装上の気づき

 

今後の課題

問題データ

小問ごとにタイトル(ex:都道府県と果物)、学年(ex:s3)、分野1(ex:社会)、分野2(ex:地理)、分野3(ex:農業)、のようなデータを盛り込んでおいて、利用しやすくする

表示

表示する内容とレイアウトを整理する。

ページ構成

現在のページ構成は
A名前や問題・レベルなどを入力選択するページ(start.php)

Bクイズの問題、答え、解説ページ(内容を切り替え)(main.php)

C結果表示のページ(result.php)

Aに戻る

の3ページ構成だが、ページを分ける方がメンテナンスが楽になる気がする。

A名前を入力するページ(start.php)

生徒には特別な処理(専用の問題や苦手問題を追加)

Bレベル・問題・モードを選ぶページ(select.php)

C問題と選択肢のページ(quizQ.php)

D答えと解説のページ(quizA.php)→問題数だけループ(Cに戻る)

E結果のページ(result.php)→「再挑戦」Cに戻る

「問題選択」Bに戻る

タイトルとURLをコピーしました