PHP入門 繰り返し処理
PHPの繰り返し構文のwhile/do~while、for/foreach命令について解説しています。
while/do~while命令
while/do~while命令には、与えられた条件式がtrue(真)である間、ループを繰り返します。while命令はループの先頭で条件式を判定(前置判定)するのに対して、do~while命令はループの最後に判定(後置判定)しています。この違いは、「ループを開始する時点で条件式がfalseである場合」に、結果として現れてきます。後置判定では、条件式に関わらず必ず1回はループが実行されますが、前置判定では、条件次第では1回もループが実行されないことがあります。
構文:while命令
while(条件式){
//条件式がtrueである間、繰り返し実行する処理
}
<?php
$i = 1;
while ($i < 6){
print "{$i}番目のループです。<br />";
$i++;
}
構文:do~while命令
do~while命令の末尾には、文の区切りを表すセミコロン(;)が必要です。
do{
//条件式がtrueである間、繰り返し実行する処理
}while(条件式);
<?php
$i = 1;
do {
print "{$i}番目のループです。<br />";
$i++;
} while ($i < 6);
無限ループ
whileを使用して永久に終了しない無限ループにすることができます。次のソースコードで無限ループになります。ただ、無限ループはサーバーに負荷をかけ、OS自体フリーズする可能性があります。
<?php
$i = 1;
while ($i < 6){
print "{$i}番目のループです。<br />";
}
for命令
for命令はあらかじめ指定された回数だけ処理を繰り返します。for命令では先頭の「初期化式」「継続条件式」「増減式」を使って、ループの継続条件/終了を管理します。
構文:for命令
for(初期化式; 継続条件式; 増減式){
//ループ内で実行する処理
}
<?php
for($i = 1; $i < 6; $i++){
print "{$i}番目のループです。<br />";
}
1、初期化式
初期化式は、forブロックに入った最初のループで一度だけ実行されます。一般的には、ここでカウンター変数(ループ変数)を初期化します。カウンター変数とはfor命令によるループの回数を管理する変数のことです。
2、継続条件式
継続条件式は、forループを継続するための条件を表します。ループを開始するたびに判定し、条件を満たさなくなったところで、forブロックを終了します。この例では、「$i < 6」なので、カウンター変数iが6未満(1~5)である間だけループを繰り返します。
3、増減式
ループ内の処理が1回終わるたびに実行されます。一般的に、カウンター変数を増減するためのインクリメント/デクリメント演算子、または、複合代入演算子で表します。ここでは、「$i++」としているので、ループのつど、カウンター変数iに1加算します。「$i+=2」とすればカウンター変数を2ずつ加算することもできます。「$i–」とすることで1ずつ減算するこも可能です。
for命令の注意点
1、無限ループはfor命令でも発生する
次のようなコードではforでも無限ループが発生します。カウンター変数$iの初期値が1で、その後は「$i–」で減算されていくだけなので、条件式は「$i < 6」がfalseになることはないからです。
for($i = 1; $i < 6; $i--){・・・}
継続条件式が省略されると、for命令は無条件にtrue(継続)とみなすためです。
for($i = 1; ; $i++){・・・} //継続条件式を省略
for(; ;){・・・} //すべての式を省略
2、カウンター変数に浮動小数点型を利用しない
カウンター変数に浮動小数点型を利用するのは意味がないだけでなく、有害です。
3、ブロックは以下でカウンター変数を操作しない
次のようなコードは避けましょう。カウンター変数は増減式のみで更新する。
<?php
for($i = 1; $i < 6; $i++){
if($i % 2 == 0){
$i++;
}
print "{$i}<br />";
}
カンマ演算子
カンマ演算子(,)を利用することで、初期化式、継続条件式、増減式に複数の式を指定することもできます。カンマで区切られた式は先頭から順に実行されます。
この場合、print命令と加算子とが増減式としてループのたびに実行されます。ブロックがない場合は、「for(~);」のように末尾をセミコロン(;)で終了します。
<?php
for($i = 1; $i < 6; print "{$i}番目のループです。<br />" , $i++);
ここでは、初期化式でカウンター変数$iと$jを初期化し、継続条件式で両者の積を求め、さらに増減式では$iと$jの双方をインクリメントしています。
<?php
for($i = 1 , $j = 1; $result = $i * $j , $i < 6; $i++, $j++){
print "{$i} × {$j}={$result}<br />";
}
foreach命令
foreach命令は、指定された配列/連想配列の要素を取り出して、先頭から順番に処理します。キー変数/値変数(まとめて仮変数とも言います)は、配列や連想配列から取り出した各要素のキー/値を一時的に格納する変数です。foreachのブロック内では、この仮変数を介して個々の要素にアクセスします。
構文:foreach命令(配列)
foreach(配列 as 値変数){
//ループ内で実行する処理
}
<?php
$data = ['山田', '田中', '鈴木','井上','和田'];
foreach ($data as $value){
print "名前は{$value}<br />";
}
構文:foreach命令(連想配列)
foreach(連想配列 as キー変数 => 値変数){
//ループ内で実行する処理
}
「foreach($data as $key => $value)」の構文は、通常配列に対しても利用できます。その場合、仮変数$keyには配列のインデックス番号がセットされます。
<?php
$data = ['山田' => '男', '田中' => '女',
'鈴木' => '男','井上' => '男',
'和田' => '女'];
foreach ($data as $key => $value){
print "{$key}:{$value}<br />";
}
for命令による書き換え
foreach命令は、for命令で書き換えることもできます。countは配列のサイズを求めるための関数です。この例であれば0からcount($data)の範囲でカウンター変数を変化させることで、配列内のすべての要素を取得しています。
<?php
$data = ['山田', '田中', '鈴木','井上','和田'];
for ($i = 0; $i < count($data); $i++){
print "名前は{$data[$i]}<br />";
}
値変数の参照渡し
foreachブロックの中で配列の要素を変更したいという場合には、値変数を参照渡しする必要があります。参照わたしとは、値を格納したメモリ上のアドレスをコピーする手法です。値変数の頭に「&」演算子を付与することで、配列の内容は値変数に参照渡しされるようになります。参照渡しされた先での変更は、もともとの変数にも反映されます。
<?php
$data = ['山田', '田中', '鈴木','井上','和田'];
foreach ($data as &$value){
$value = 'New' . $value;
}
print_r($data);
foreach命令での分割代入
foreach命令と分割代入を組み合わせることで、入れ子の配列をループ内で分解することも可能です。
<?php
$books = [
['わかるPython',3500],
['わかるJava',2500],
['わかるC#',3000],
];
foreach($books as [$title, $price]){
print "{$title} ({$price}円) <br />";
}
同様に、連想配列の配列であれば次のようになります。
<?php
$books = [
[ 'title' => 'わかるPython','price' => 3500],
[ 'title' => 'わかるJava','price' => 2500],
[ 'title' => 'わかるC#','price' => 3000],
];
foreach($books as [$title => $title, 'price' => $price]){
print "{$title} ({$price}円) <br />";
}
配列への代入
分割代入では、配列形式の変数への代入も可能です。これを利用して、連想配列の配列から特定のキーを取り出して、新たな配列を生成することも可能です。➊の部分は、連想配列$bookからisbnキーのものを取り出し、配列$isbnの末尾($isbn[])に追加します。
<?php
$books = [
[ 'isbn' => '978-4-7981-6333-1' , 'title' => 'わかるPython'],
[ 'isbn' => '978-4-7981-6333-2' , 'title' => 'わかるJava'],
[ 'isbn' => '978-4-7981-6333-2' , 'title' => 'わかるC#'],
];
foreach($books as $book){
['isbn' => $isbn[]]; = $book; //➊
}
print_r($isbn);