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 こいつとセットで覚えることが重要です。
登場人物の紹介はだいたい終わったので、それでは解説を始めます。
多分、凄く長くなりますが、丁寧に解説しますのでよろしくお願いいたします。
連想配列と普通の配列の2種類がある
配列には添え字がついた連想配列と、ただの数字の配列の2種類があります。
今回の例題で使っているのは「連想配列」の「多次元配列」になっています。
ややこしいのは承知なんですが、こういう使い方が実践的なんでしょうがない。

上の図で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; } ?>
foreach($配列名){} これが基本形です。
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>' ?>
出力結果
クイズ形式のプログラムの解説
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まで増やしました。
配列を増やしたまま、さっきのプログラムを展開するとこうなります。
出力結果
メインのプログラムは変更せずに、配列の数を増やしただけで、問題を好きなだけ増やせるわけですね。
素晴らしくないですか?配列。
