PHP実習:配列とforeach、二次元配列
なんだかんだでPHPの勉強をちゃんとしようと決めて行動を始めてから1か月くらいになります。楽しいです。
第6章-01
今回から配列を用いたデータ管理について学んでいく。まずは下のコードの動作確認。
<?php
$array=array(); // 配列として初期化
$array='りんご';
$array='みかん';
$array='ばなな';
var_dump($array);
$array=array()と書くことにより、$arrayは配列として認識される。この配列からとk帝のデータのみを取り出す場合、以下のように配列の添え字を指定すればよい。
<?php
$array=array(); // 配列として初期化
$array='りんご';
$array='みかん';
$array='ばなな';
echo $array[2];
こうすることで、画面に「ばなな」と表示される。
また、[0][1][2]などと数字のついた箇所をキーという。キーは添え字(自動的に降られる数字)以外にもこちらで名づけることもできる。
<?php
$array=array(); // 配列として初期化
$array['name']='鈴木';
$array['hobby']='テニス';
$array['mail']='sample@sample.com';
var_dump($array);
上のコードについて、以下のように書き換えればこちらで指定したキーを用いて指定することもできる。
<?php
$array=array(); // 配列として初期化
$array['name']='鈴木';
$array['hobby']='テニス';
$array['mail']='sample@sample.com';
echo $array['hobby']; //キーがhobbyのデータのみを出力
また、配列の書き方は他にも存在する。複数のデータを一度に格納する場合、以下のように書くとよい。
<?php
$array=array(); // 配列として初期化
$array=array('name'=>'鈴木','hobby'=>'テニス','mail'=>'sample@sample')
こうすることで複数のデータを一度に配列に格納することができる。
自身でキー名を名づけた配列を「連想配列」と呼ぶ。また、上のコードで使っている「=>」はダブルアロー演算子といい、連想配列を作るときに使われる。
第6章-02
配列の要素数に応じて繰り返し処理を行うforeach()について学ぶ。for-each。
<?php
$array=array();
$array=(
'name' => '鈴木',
'hobby' => 'テニス',
'mail' => 'sample@sample.com'
);
foreach($array as $key => $var){
echo $key.':'.$var.'<br>';
}
foreach()は配列の要素数に応じて繰り返し処理を行う。
foreach( 【配列】as【キー名】=>【データを格納する変数】)という構成になる。
このとき、$keyにはキー名、$varには中身のデータが代入される。変数はこの時点で初めて初期化されるので、foreach($array as $column => $item)というように自由に変数名を指定することができる。
しかし、いきなりだがforeach()においてキー名は省略して書くことができる。キー名はプログラマが中身を把握するための名前であり、そのまま出力することは多くない。
<?php
$array=array();
$array=(
'name' => '鈴木',
'hobby' => 'テニス',
'mail' => 'sample@sample.com'
);
foreach($array as $var) {
echo $var.'<br>';
}
第6章ー02 練習問題
- 下記のコードに加筆して以下の課題を解け。
<?php
$array=array(
'name'=>'佐藤',
'age'=>'27',
'blood'=>'AB'
}
- キー「age」の中身だけを指定して出力せよ。
- foreach()を使用して配列の中身をすべて出力せよ。
<?php
$array=array(
'name'=>'佐藤',
'age'=>'27',
'blood'=>'AB'
}
// 課題1
echo $array['age'].'<br>';
// 課題2
foreach($array as $var){
echo $var.'<br>';
}
第6章-03
二次元配列について学ぶ。「配列の中に配列を入れる」というイメージであり、これを使ってデータベースから取得したデータと同じような状態になると言える。
<?php
$arrays=array(
0 => array(
'name' => '鈴木',
'hobby' => 'テニス',
'mail' => 'sample@sample.com',
),
1 => array(
'name' => '山田',
'hobby' => 'パソコン',
'mail' => 'sample2@sample.com',
),
2 => array(
'name' => '斎藤',
'hobby' => '水泳',
'mail' => 'sample3@sample.com',
),
);
このコードから「山田」の名前だけを出力するには…
echo $arrays[1]['name'];
と後ろに書けばよい。
「$arraysという大きな箱の中に$arrayという小さな箱があり、その小さな箱の中にそれぞれname、hobby、mailがあるイメージ」とのこと。
では、HTMLの中で配列を出力していこう。先ほどまでのコードの後ろにHTMLを書いていく。
<?php
$arrays=array(
0 => array(
'name' => '鈴木',
'hobby' => 'テニス',
'mail' => 'sample@sample.com',
),
1 => array(
'name' => '山田',
'hobby' => 'パソコン',
'mail' => 'sample2@sample.com',
),
2 => array(
'name' => '斎藤',
'hobby' => '水泳',
'mail' => 'sample3@sample.com',
),
);
<html>
<body>
<table border="1">
<tr><th>名前</th><th>趣味</th><th>メールアドレス</th></tr>
<tr><td>鈴木</td><td>テニス</td><td>sample@sample.com</td></tr>
</table>
</body>
</html>
これで、タグ内が既に記述されている静的なページができる。
現在「鈴木」や「テニス」が記述されている箇所を削除し、以下のように書き換え。
<table border="1">
<tr><th>名前</th><th>趣味</th><th>メールアドレス</th></tr>
<?php foreach ($arrays as $row) { ?>
<tr>
<td><?php echo $row['name']; ?></td>
<td><?php echo $row['hobby']; ?></td>
<td><?php echo $row['email']; ?></td>
</tr>
<?php } ?>
</table>
二次元配列$arraysには配列が格納されており、これを$rowと名付けて取り出している。echoで表示するときにはさらに連想配列のキー名を指定する必要があるので、$row配列のキーnameをechoで表示したいときは$row['name']と記述している。
ちなみに、デザイン的な観点ではHTMLタグはechoで出力しない方がよいと言われているらしい。
第6章-04 実習
今回はチェックボックスの値を取得し、送信ボタンで次のページに進んだら選択したものが表示されるという仕組みを作る。制作の流れとしては、
- 送信ページ(チェックボックスで選択するページ)を作る
- 配列としてデータを取得する
- foreachを使って受け取り側のページで表示する
という風になる。要件定義としては、
- checkboxを使って好きな色を選択し、送信できるようにする
- 取得後のデータはリスト表示する
- 出力時はセキュリティを意識してエスケープ処理を行う
となる。エスケープ処理とは。
まずは送信ページを作成する。次のコードを書く。
<html>
<body>
<h1>チェックオックスを使ったフォーム</h1>
<p>好きな色を選択してください(複数選択可)</p>
<form action="checkbox_receive.php" method="POST">
<p>
<input type="checkbox" name="colors" value="青">青
<input type="checkbox" name="colors" value="赤">赤
<input type="checkbox" name="colors" value="黄">黄
<input type="checkbox" name="colors" value="緑">緑
<input type="checkbox" name="colors" value="紫">紫
<input type="checkbox" name="colors" value="白">白
<input type="checkbox" name="colors" value="橙">橙
</p>
<input type="submit">
</form>
</body>
</html>
<input>タグにname="color"と入っていることを確認する。[]はこれから送るデータが配列であることを示すため、書き忘れるとデータが1つしか送信できない。複数のデータを送信する際には必須となる。
合わせて、受信ページとなるcheckbox_receive.phpも作成。
<?php
//チェックボックスの値を取得する
?><html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>受信ページ</h1>
<h3>好きな色</h3>
</body>
</html>
この状態でデータを受信し、var_dumpで表示する(「チェックボックスの値を~」の部分を「var_dump($_POST['colors'];)」と書き換え)。
自動的に添え字がつく形の配列として取得していることが分かる。個別にデータを取り出す場合は「$colors[0]」「$colors[2]」という風に記述する。これをリスト表示していく。
<?php
//チェックボックスの値を取得する
$colors=$_POST['colors']
//var_dump($_POST['colors']);
?><html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>受信ページ</h1>
<h3>好きな色</h3>
<?php foreach ($colors as $value) { ?>
<li><?php echo $value; ?></li>
<?php } ?>
</body>
</html>
リストとして表示することができた。
また、今回は「セキュリティを意識してエスケープ処理をする」という条件があるのでその部分について学んでいく。
フォームからの入力内容は、基本的にすべての出力時に特殊文字の変換を行っていなければならず、それはチェックボックスの際も例外ではない。チェックボックスの値はクライアント側で変更することができてしまうため、悪意のあるプログラムを送信して実行することが可能である。そこで、出力前に<>などの特殊文字やプログラムで使われるシングルクォーテーションなどのプログラム的な効果を無くしてしまう必要がある。そこで使われるのがhtmlspecialchar()というコードである。
checkbox_receive.phpのecho部分を以下のように書き換え。
<?php foreach ($colors as $value) { ?>
<li><?php echo htmlspecialchars($value,ENT_QUOTES,'utf-8'); ?></li>
<?php } ?>
htmlspecialcharsの第一引数には変換する文字列を指定する。第二引数には「ENT_QUOTES」を指定するのが一般的で、これによりシングルクォーテーションやダブルクォーテーションのどちらも変換することができる。第三引数には出力時の文字コードである「UTF-8」を指定。クライアントから受信したデータを出力する場合には必ずhtmlspecialchars()の処理を加えるようにしよう。
checkbox_receive.phpにもう少し処理を加え、このようになる。
<?php
//チェックボックスの値を取得する
$colors=$_POST['colors']
//var_dump($_POST['colors']);
?><html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>受信ページ</h1>
<h3>好きな色</h3>
<ul>
<?php foreach ($colors as $value) { ?>
<li><?php echo htmlspecialchars($value,ENT_QUOTES,'utf-8'); ?></li>
<?php } ?>
</ul>
<p>あなたの好きな色は<?php echo implode('と',$colors); ?>です。</p>
</body>
</html>
ちなみにimplodeという関数は、配列要素を文字列によって連結する働きを持つ。
公式ドキュメントの内容は以下の通り。
string implode (string $glue, array $pieces)
$glue...デフォルトは空文字
$piece...連結したい文字列の配列
すべての配列要素の順序を変えずに、各要素の間に$glue文字列を挟んで1つの文字列として返す
これにより、checkbox_receive.phpはデータを受け取るとこのようになる。
これにて実習終了!!残念ながら今回は一工夫加える箇所が思い浮かばないので、何も手を加えません。
明日は楽しみにしている映画の公開日なのでわくわくしながら寝ます。