PHPで複数問題のクイズを作るなら連想配列の多次元配列が効率的

PHPの配列ってイメージは付くけどちゃんと理解するのが難しい。 例題がわかりづらいせいだと思うんですよね。これはわかりやすい。

PHPの連想配列の多次元配列を使ったクイズの作り方

配列の解説 WEB制作

PHPプログラムにおいて「配列」を理解することは避けては通れません。配列がないと話にならないレベルでよく使う命令文です。そんな配列の中でもわかりづらい連想配列と多次元配列を使ったクイズコンテンツの作り方の紹介です。丁寧に解説しています。

公開日:
最終更新日:

配列の解説 関連ワード #111
配列
多次元配列
連想配列
クイズの作り方
  • Twtterでシェアする
  • はてなブックマーク
  • フェイスブックでシェア
  • ポケットでシェア
  • LINEで友達に送る

PHPプログラムの鬼門 配列について

どんなプログラムにも備わっているであろう便利な機能の1つ、配列についてわかりやすく説明したいと思います。

配列って個人的に、最初の難関だとおもうんですよ。
ギターでいうセーハーのようなイメージ。

ギターもセーハー覚えると、弾ける曲が増えるじゃないですか。それと似たようなポジションにいますよ、配列は。

なんとなく、配列ってもののイメージはわくんですが、実際どういう使い方をするのかとか、どんなときに役に立つのかなどを説明していきたいと思います!

配列ってなに?なんの役にたつの?

配列っていうのは、関連性のある情報を1つのかたまりにしてまとめるのに使います。
恒例の漢字クイズを例に上げて実際に使ってみます。

漢字の読み方を答えるクイズの問題を配列化します。

<?php
$kanji_q_array["Q1"]["設問"] = "薔薇";
$kanji_q_array["Q1"]["回答1"] = "バラ";
$kanji_q_array["Q1"]["回答2"] = "ローズ";
$kanji_q_array["Q1"]["回答3"] = "チューリップ";
$kanji_q_array["Q1"]["回答4"] = "ヒマワリ";
?>

解説すっ飛ばして、今日のゴールを先出しますね。

配列とそれを展開するforeachを使った作例

<?php
foreach($kanji_q_array as $key => $val){
	echo '<h3>'.$key.' '.$kanji_q_array[$key]["設問"].'</h3>';
	foreach($kanji_q_array[$key] as $key2 => $val2){
		if($key2 != '設問'){
			echo $val2.'<br>';
		}
	}
}
?>

▼この例を実際に実行するとこうなります

Q1 薔薇

バラ
ローズ
チューリップ
ヒマワリ

配列をうまく使うと、コードをぎゅっと省略できるんですね。
これを先に伝えたかったんです。

配列とforeachでコードを効率化できる

この記事を読了すると意味がわかります。

配列を覚えるとそれに付随した命令文も覚える

配列単体だとあまり意味がないんです。
配列を展開する foreach こいつとセットで覚えることが重要です。

登場人物の紹介はだいたい終わったので、それでは解説を始めます。
多分、凄く長くなりますが、丁寧に解説しますのでよろしくお願いいたします。

連想配列と普通の配列の2種類がある

配列には添え字がついた連想配列と、ただの数字の配列の2種類があります。

今回の例題で使っているのは「連想配列」の「多次元配列」になっています。
ややこしいのは承知なんですが、こういう使い方が実践的なんでしょうがない。

多次元配列な連想配列

これを理解できれば効率が大幅にUP!

上の図でKEYと書かれた=(イコール)の左側がキーになります。
これが2つ並んでいるので「多次元配列」と呼び、キーに名前がついているのが「連想配列」になります。

$kanji_q_array というのが配列の名前で、_array はつけなくてもいいんですが、配列だよ、とわかりやすくするために、配列の変数名には array とつけるのがオススメです。

漢字クイズの配列で $kanji_q_array であると。

PHPによる連想配列の多次元配列の作り方講座

まず最初に、なんの配列をどういった目的で作るかを考えてください。
これがないとダメ。

今回は、漢字クイズで使う問題と、選択肢4つを配列にします。
もっと言うとQ2、Q3と続く予定で作っています。

出題が1問で終わるなら、多次元にする必要はないわけです。
Q1なんていうくくりがいらないわけですから。

$kanji_q_array["Q1"]
$kanji_q_array["Q2"]
$kanji_q_array["Q3"]
多次元配列は設計が大事

多次元配列は設計が命

と、こんな感じで設問数が増えていく配列を想定しています。

配列 ["Q1"]の中身を考えて作る

漢字クイズの構成を考えると、設問とそれに対する選択肢4つ(任意の数)でクイズが作れます。
選択肢は好きなだけ増やしてもらって構わないんですが、誤答を考えるが大変なので3つか4つくらいがいいんじゃないですかね。

次のキーは「設問」と「選択肢×4」と決まりました。
それを配列にあてていきます。

$kanji_q_array["Q1"]["設問"]
$kanji_q_array["Q1"]["回答1"]
$kanji_q_array["Q1"]["回答2"]
$kanji_q_array["Q1"]["回答3"]
$kanji_q_array["Q1"]["回答4"]

キーには日本語つかってOKです。
但し、同じ名前でキーを作ると、後から作ったものに値が上書きされてしまうので、回答にはナンバリングを振ります。

$kanji_q_array["Q1"]["回答1"] この形になったら =(イコール) の右側の値に何を入れればいいかわかりますよね?
値をうめていきましょう。

$kanji_q_array["Q1"]["設問"] = "薔薇";
$kanji_q_array["Q1"]["回答1"] = "バラ";
$kanji_q_array["Q1"]["回答2"] = "ローズ";
$kanji_q_array["Q1"]["回答3"] = "チューリップ";
$kanji_q_array["Q1"]["回答4"] = "ヒマワリ";

漢字クイズに必要なパーツを埋めていくというわけです。
設問「薔薇」と、その読み方4つが「回答1~4」の値に入ります。

出来上がった配列をみてみよう

初めて見たときは意味が分からなかった「多次元配列」の「連想配列」がものすごくわかりやすくなったと思います。
この配列が意味するところ分かりますよね?

多次元配列な連想配列

こういう風に作られているわけです

ちゃんと理解して使えば、簡単なんですよ、配列なんて。
勘のいい方ならうすうす気づいていると思いますが、すごく便利なんです。

これのQ1をQ2に変えれば、2問目が作れるわけです。

では、作った配列を展開してみましょう。
foreach!こいつもわかりづらい。

配列を展開する foreach を解説

foreachは配列にしか使えないんです。配列を展開するためだけに生まれてきた命令文です。

というわけで配列に使ってみましょう。

<?php
foreach($kanji_q_array as $key => $val){
	echo $key;
}
?>		

foreah($配列名){} これが基本形です。
foreach() のなかに配列名を入れます。

()の中に入れた 配列名のあとに as と入れて、$key => $val と続けます。
$key と $val は好きな名前で問題ないです。 => これの左側がキーの変数名、 右側が値 となります。

foreach($kanji_q_array as $key => $val)の結果

foreach($kanji_q_array as $key => $val){ echo $key;}の結果は「Q1」と表示されます。

これは多次元配列の左側から展開されるので、1番目のKEYの添え字が表示されているわけです。

ちなみに echo $val とすると、警告メッセージが表示されて Array と言われます。

echo は配列を表示させる力を持っていないので、警告とともに配列を意味する「Array」が表示されます。

連想配列が2つあるのでforeachも2回使う

foreach の1番目のキーである「Q1」は出力できましたが、その先のキーと値が欲しいわけです。
多次元なのでもう一回foreachを回しましょう。

<?php
foreach($kanji_q_array as $key => $val){
	foreach($kanji_q_array[$key] as $key2 => $val2){
		echo $key2;
		echo $val2;
		echo '<br>';
	}	
}
?>		

出力結果

設問薔薇
回答1バラ
回答2ローズ
回答3チューリップ
回答4ヒマワリ

これで、配列に設定した値が全部取得できました。

2回目のforeachの中身を解説しましょう。

foreach($kanji_q_array[$key] as $key2 => $val2)

$kanji_q_array[$key] の$key には「Q1」が入ります。

今回作った配列がこうです。

$kanji_q_array["Q1"]["設問"] = "薔薇";
$kanji_q_array["Q1"]["回答1"] = "バラ";
$kanji_q_array["Q1"]["回答2"] = "ローズ";
$kanji_q_array["Q1"]["回答3"] = "チューリップ";
$kanji_q_array["Q1"]["回答4"] = "ヒマワリ";

foreach($kanji_q_array[$key] as $key2 => $val2)の中身を展開しているので、
$kanji_q_array["Q1"] の次のキーと値が展開されます。

<?php
foreach($kanji_q_array as $key => $val){
	foreach($kanji_q_array[$key] as $key2 => $val2){
		echo $key2;
		echo $val2;
		echo '<br>';
	}	
}
?>		

$key2 には 「設問」「回答1~4」が展開され、
$val2には「薔薇」「バラ」「ローズ」「チューリップ」「ヒマワリ」が展開されました。

foreachは配列の中身を全部展開するまでループされます。
そのため、Q1が「設問」から「回答4」まで全部で5個あるので5回ループしているわけです。

いらないキーは出力しなければよい

今回の出力結果をもう一度みてみましょう。

出力結果

設問薔薇
回答1バラ
回答2ローズ
回答3チューリップ
回答4ヒマワリ

配列のキーの添え字が邪魔じゃないですか?
「設問」と「回答1~4」の文字いらないので、こいつらは出力しないようにします。

$key2 を削除すればOK

<?php
foreach($kanji_q_array as $key => $val){
	foreach($kanji_q_array[$key] as $key2 => $val2){
		echo $val2;
		echo '<br>';
	}	
}
?>		

出力結果

薔薇
バラ
ローズ
チューリップ
ヒマワリ

スッキリしました。ゴールは近いですね。
これでほぼ完成なのですが、何問目かを示す「Q1」はあってもよいので、今度は逆に「Q1」を出力してみます。

配列の1番目のキーだけ出力

<?php
foreach($kanji_q_array as $key => $val){
	echo $key;
	foreach($kanji_q_array[$key] as $key2 => $val2){
		echo $val2.'<br>';
	}
}
?>

出力結果

Q1薔薇
バラ
ローズ
チューリップ
ヒマワリ

foreach($kanji_q_array as $key => $val){
echo $key;

1回目のforeach の $key を出力してやればいいわけですね。

ここまでくれば、もう完成ですよ。
あとはHTMLをうまく組み合わせてクイズの形式に仕上げれば、配列を使ったクイズの完成です。

ここまできたので完成形まで作ってみますね。

クイズの出題形式に合わせて改修

クイズとして使うにはformタグが必要になるので、formタグを追加し、選択肢は<input type="radio">を使います。

説明してなかったんですが、配列は配列に添え字を指定すれば、foreachを使わなくても表示させることができます。

配列の添え字を指定すれば値が表示できる

配列の添え字を指定すれば値が表示できる

echo $kanji_q_array["Q1"]["設問"]

と打てば、配列の中身である「薔薇」が表示されます。

<?php
echo '<form>';
foreach($kanji_q_array as $key => $val){
	echo '<h3>'.$key.' '.$kanji_q_array[$key]["設問"].'</h3>';
	foreach($kanji_q_array[$key] as $key2 => $val2){
		if($key2 != '設問'){
			echo '<label><input type="radio" name="'.$key.'" value="'.$val2.'">'.$val2.'</label><br>';
		}
	}
}
echo '</form>'
?>

出力結果

Q1 薔薇





クイズ形式のプログラムの解説

4行目のコードが少しトリッキーになっていますが、こちらを説明いたします。

echo '<h3>'.$key.' '.$kanji_q_array[$key]["設問"].'</h3>';

$key には配列の1番目のキーが入っているので「Q1」が展開されます。
$kanji_q_array[$key]["設問"] なのでこいつのは書き換えると

echo $kanji_q_array["Q1"]["設問"]

になるわけです。

つまりは「薔薇」がでてきます。

6行目のif文の解説

6行目に突然if文がでてきます。

if($key2 != '設問'){
	echo '<label><input type="radio" name="'.$key.'" value="'.$val2.'">'.$val2.'</label><br>';
}

これは、4行目ですでに設問を取り出しているので、もう設問はいらないわけです。

$key2 は2回目のキーが表示されます。
この$key2のなかに「設問」が入っているので、$key2 != '設問' で設問だったら何もしなくてよいよ。と書いてあるわけです。

「!=」は論理否定という意味で、〇〇じゃない場合、という意味になります。

ラジオボタンの解説

echo '<label><input type="radio" name="'.$key.'" value="'.$val2.'">'.$val2.'</label><br>';

これはPHPではなく、HTMLの話なのですが、radio は同一の name属性のなかで、1つの選択肢を選べる、というタグです。

name="'.$key.'"

このname="'.$key.'" は「Q1」が入ってますので、4つの選択肢のnameが全部「Q1」になり、4つの選択肢から1つの回答を選べるようになります。

次にvalueの値ですが、これは配列の回答がはいっているわけですね。

value="'.$val2.'"

配列の2番目の添え字の「値」が代入されます。

もう一度、radioの全貌を見直してみましょう。

echo '<label><input type="radio" name="'.$key.'" value="'.$val2.'">'.$val2.'</label><br>';

$key には「Q1」が入り、$val2には配列の「値」が入ります。
これをHTMLで展開されたもので書き直すと、

<label>
<input type="radio" name="Q1" value="バラ">バラ
</label>

このようにレンダリングされるわけです。
これがループして4つの選択肢になります!

配列を使って作ると汎用性が高まる

もう少しで終わります。頑張ってください。

今回作ったこのプログラム、配列の中身を増やすだけで設問が勝手に増えます。

<?php
echo '<form>';
foreach($kanji_q_array as $key => $val){
	echo '<h3>'.$key.' '.$kanji_q_array[$key]["設問"].'</h3>';
	foreach($kanji_q_array[$key] as $key2 => $val2){
		if($key2 != '設問'){
			echo '<label><input type="radio" name="'.$key.'" value="'.$val2.'">'.$val2.'</label><br>';
		}
	}
}
echo '</form>'
?>

これ。ここが配列の素晴らしいところです。

用意した配列がこちら

<?php
$kanji_q_array["Q1"]["設問"] = "薔薇";
$kanji_q_array["Q1"]["回答1"] = "バラ";
$kanji_q_array["Q1"]["回答2"] = "ローズ";
$kanji_q_array["Q1"]["回答3"] = "チューリップ";
$kanji_q_array["Q1"]["回答4"] = "ヒマワリ";
?>

この配列を増やすだけで、設問と選択肢が増えます。
増やしてみましょう。配列を。

$kanji_q_array["Q1"]["設問"] = "薔薇";
$kanji_q_array["Q1"]["回答1"] = "バラ";
$kanji_q_array["Q1"]["回答2"] = "ローズ";
$kanji_q_array["Q1"]["回答3"] = "チューリップ";
$kanji_q_array["Q1"]["回答4"] = "ヒマワリ";

$kanji_q_array["Q2"]["設問"] = "蘭";
$kanji_q_array["Q2"]["回答1"] = "ラン";
$kanji_q_array["Q2"]["回答2"] = "ヒップ";
$kanji_q_array["Q2"]["回答3"] = "ベリー";
$kanji_q_array["Q2"]["回答4"] = "コナン";

$kanji_q_array["Q3"]["設問"] = "木瓜";
$kanji_q_array["Q3"]["回答1"] = "ボケ";
$kanji_q_array["Q3"]["回答2"] = "キュウリ";
$kanji_q_array["Q3"]["回答3"] = "モッケ";
$kanji_q_array["Q3"]["回答4"] = "キヅメ";

Q1~Q3まで増やしました。
配列を増やしたまま、さっきのプログラムを展開するとこうなります。

出力結果

Q1 薔薇





Q2 蘭





Q3 木瓜





メインのプログラムは変更せずに、配列の数を増やしただけで、問題を好きなだけ増やせるわけですね。

素晴らしくないですか?配列。

配列とforeachでコードを効率化できる

ここまで読んでいただいた方にはわかるはず

  • Twtterでシェアする
  • はてなブックマーク
  • フェイスブックでシェア
  • ポケットでシェア
  • LINEで友達に送る

次の記事はこちら

プロフィール:fuchi WEBクリエイター

fuchi
WEBクリエイター / 個人事業主
39歳 / ♂ / 鳥好き

WEB制作とWEBマーケティングをやってきました。
PHPとMysqlを使って面白いことをやりたいと模索中です。

ロリポップ!のレンタルサーバーを使っています

プロフィール詳細はこちら

文中で紹介している商品

誰もがあきらめずにすむPHP超入門

誰もがあきらめずにすむPHP超入門 データベース処理 【誰もがあきらめずにすむPHP超入門】

1,848円 (Amazon価格)

PHP 関連記事はこちら すべての WEB制作 記事はこちら

ブログ人気の記事・レビュー

新着記事

カテゴリリスト

プロフィール:fuchi WEBクリエイター

fuchi
WEBクリエイター / 個人事業主
39歳 / ♂ / 鳥好き

WEB制作とWEBマーケティングをやってきました。
PHPとMysqlを使って面白いことをやりたいと模索中です。

ロリポップ!のレンタルサーバーを使っています

プロフィール詳細はこちら

配列の解説関連・オススメ商品 amazon