【連載】春の新入社員におくるPHP超入門 ~ その4:繰り返し処理 – while文・for文・foreach文 –

こんにちは。サイオステクノロジーの川田です。

PHPを始めてみよう!触ってみよう!と考えている方向けへのPHP超入門をお届けしております。

今回は繰り返し処理についてご紹介致します。第4回になります。
未経験の後輩は多重ループがとても苦手なようでした。

そして!ループで怖いのが無限ループです!
私は若い時に無限ループで開発サーバーを固まらせた経験があります。
もう心臓バクバクの冷や汗ダラダラでした:(;゙゚’ω゚’):

使用するツールはこちらです。
環境の詳細についてはアジェンダの「1.環境構築」へ(/・ω・)/

  • Visual Studio Code
    拡張機能:Remote Development

  • Docker

繰り返し処理について

繰り返し処理とは条件を満たしている間は同じ処理を繰り返し実行すること
例えば「Hello World!」を10回出力したいとします。
繰り返し処理を使わなければ、以下のようになります。

<?php
echo "1回目:Hello World!";
echo "2回目:Hello World!";
echo "3回目:Hello World!";
echo "4回目:Hello World!";
echo "5回目:Hello World!";
echo "6回目:Hello World!";
echo "7回目:Hello World!";
echo "8回目:Hello World!";
echo "9回目:Hello World!";
echo "10回目:Hello World!";

これを見てどう思われましたか?
これが100回1000回になってきたらと考えると「同じ単語を繰り返してるだけだし。もっと効率よく出力できるのでは!?」と思いますよね。

では繰り返し処理を使うとどうなるのか。簡単にフローチャートを作成しました。

無限ループになるとどうなる?

無限ループ!無限ループ!って実際になったらどうなるの?と思われますよね。
まず無限ループとはどういうことなのか!

無限ループ
無限に処理が繰り返されること。永久ループとも言います。

先ほどのフローチャートでも記載しましたが、
「10回目まで処理を繰り返す」という条件でカウントするのを忘れてしまうと 永遠に10以下のため無限に処理が繰り返されてしまいます。
無限ループになるとCPUの使用率が100%になったりと負荷がかかります。一度入ってしまうと、サーバーを直接停止なんてことも、、、:(;゙゚’ω゚’):
共用サーバーの場合は固まってしまう可能性もあるので注意が必要です!
私はバグで処理が終わらないという不具合対応で再現確認をしていたら、見事に無限ループに入ってしまいました。
固まってしまいコマンドで止めようにも止められない状況でした;;(共用サーバー)

もし今この環境で無限ループになったら焦らずターミナルに「Ctrlキー + C」を行うと終了します。
ちなみに無限ループになるとこんな感じです。止めないと永遠に「1回目:Hello World!」が出力されます。

1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello World!
1回目:Hello^C
root@2c51effb8747:/var/www/html# 

ループを扱う場合は十分に注意してください!

今回は「☞while文」「☞for文」「☞foreach文」をご紹介します。

while

while文はPHPで最も簡単なループになります。
指定した式がtrueの間、繰り返しを実行します。基本形は以下のようになります。

while ( 式 ) {
    // 繰り返し行う処理
}

Hello World!を10回出力していきたいと思います!

<?php
$i = 1;
while ( $i <= 10 ) {
    echo $i . "回目:Hello World!\n";
    $i++;  
}

ループ処理を使うことで、echo文1つで10回分の「Hello World!」を出力できました!

1回目:Hello World!
2回目:Hello World!
3回目:Hello World!
4回目:Hello World!
5回目:Hello World!
6回目:Hello World!
7回目:Hello World!
8回目:Hello World!
9回目:Hello World!
10回目:Hello World!

ではもう一つの書き方はこちらです。同じようにまた出力してみます!

while ( 式 ) :
    // 繰り返し行う処理
endwhile;

whileの中は先ほどと変わらないです。

<?php
$i = 1;
while ( $i <= 10 ):
    echo $i . "回目:Hello World!\n";
    $i++;
endwhile;

出力結果も同じです。

1回目:Hello World!
2回目:Hello World!
3回目:Hello World!
4回目:Hello World!
5回目:Hello World!
6回目:Hello World!
7回目:Hello World!
8回目:Hello World!
9回目:Hello World!
10回目:Hello World!

※「 $i++ 」を記述しなかった場合、 $i が永遠に10以下なので「無限ループ」となります!
次はfor文について説明していきます。

for

for文は繰り返し処理のなかでもよく使われているループ処理です。
このように記述します。

for ( 初期値; 条件式; 増減式 ) {
    // 繰り返し行う処理
}

初期値:ループ開始時に実行されます。※1回だけ
条件式:この式の値がtrueの場合ループは継続されます。値がfalseになったら実行は終了します。
増減式:各繰り返し後に実行されます。

各式は空にすることもできます。まずはよく見る全て記述した場合。

<?php
for ( $i = 1; $i <= 10; $i++ ) {
    echo $i . "回目:Hello World!\n";
}

出力内容はwhile文と同じです。
$iは1からスタートし、1回目の出力が終わったら$iに1を足しています。10回より大きかったら処理が終了します。

次は2つ目の条件式の部分を空にしてみます。

<?php
for ($i = 1; ; $i++) {
    if ( $i > 10 ) {
        break;
    }
    echo $i . "回目:Hello World!\n";
}

出力内容は変わりません。 10より大きかったらbreakでfor文を抜けます。
if文($i > 10)を忘れてしまうと無限ループになります!

初期値、条件式、増減式の3つを空にするとこうなります。

<?php
$i = 1;
for ( ; ; ) {
    if ( $i > 10 ) {
        break;
    }
    echo $i . "回目:Hello World!\n";
    $i++;
}

というような書き方もできます。
while文とはまた違った記述ですよね!次はforeach文です。

foreach

私は結構foreach文好きなんですよね^^
foreach文が使えるのは配列オブジェクトのみです。 別の型や初期化前の変数に対して使うとエラーになります。
while文やfor文のように終了条件を記載する必要はありません。
なぜなら配列の要素を全て繰り返したら処理が終了するからです。記述方法を見てみましょう。

<?php
foreach ( [配列変数] as [要素変数] ) {
    // 繰り返し行う処理
}

連想配列の場合は以下のように記述します。

<?php
foreach ( [配列] as [キー変数] => [要素変数] ) {
    // 繰り返し行う処理
}

foreach文を使って文字列を出力してみましょう。

<?php
$fruits = array("オレンジ", "レモン", "リンゴ", "ナシ");

foreach ($fruits as $value) {
    echo "$value\n";
}

$fruitsという配列にはオレンジ、レモン、リンゴ、ナシが格納されています。
$valueは$fruitsの中身を1つずつ取り出して出力しています。
出力結果の通り、1つずつ出力されていることがわかります。

オレンジ
レモン
リンゴ
ナシ

もう一つの方法もやってみましょう!連想配列を作成します。

<?php
$fruits = array( "orange"=>"オレンジ", "lemon"=>"レモン", "apple"=>"リンゴ", "pear"=>"ナシ" );

foreach ( $fruits as $key => $value){
    echo $key . ":" . $value . "\n";
}

連想配列はキーを指定して作成します。今回はキーを英語としています。
出力結果はこの通りです。

orange:オレンジ
lemon:レモン
apple:リンゴ
pear:ナシ

以上がforeach文の記述方法でした。
繰り返し処理として「while文」「for文」「foreach文」をご紹介致しました。

繰り返し処理を実装していくと、繰り返しの途中で強制的に抜けたい!スキップしたい!といった場面も出てくると思います。

そのような場合は「☞break文」と「☞continue文」を使います。
この2つの違いについて確認してみましょう。

breakとcontinueの違い

breakとcontinueの違いとはなに!?こういうときはどっちを使うべきなの!?となりますよね。

break:現在実行中のwhile文、for文、foreach文、do-while文、switch文の実行処理を終了する。
continue:現在繰り返し中の残りの処理をスキップし次の繰り返し処理条件へ。

break

break文を使うことで現在実行中のループを途中で抜けることができます。
どういうことか。for文を使って実装してみます。

<?php
for ( $i = 1; $i <= 10; $i++ ) {
    if ( $i == 8 ) {
        break;
    }
    echo $i . "回目:Hello World!\n";
}

if文を途中に追加しました。
breakを入れたことにより$iが8になったら処理を途中で抜けるということになります。
それ以降の処理は実行されず、7回まで出力されていることがわかります。

1回目:Hello World!
2回目:Hello World!
3回目:Hello World!
4回目:Hello World!
5回目:Hello World!
6回目:Hello World!
7回目:Hello World!

breakはオプション引数があり、ネストしたループ構造を抜ける数を指定することができます。
省略した場合は「break 1」となります。

<?php
for ( $i = 1; $i <= 10; $i++ ) {
    switch ( $i ) {
        case 5:
            break 1; // switchを抜ける
        case 8:
            break 2; // switchとwhileを抜ける
        default:
            echo $i . "回目:Hello World!\n";
            break; // break 1と一緒。switchを抜ける
    }
}

例文はfor文の中にswitch文が実装されています。$iが5になったらswitch文を抜けます。
まだfor文の中にいます! $i=5でswitch文を抜けているためdefaultで5回目の出力がないですよね!
8回目にきた時「break 2」とすることでswitch文、for文両方を抜けて9回目以降の処理は行われずに終了します。

1回目:Hello World!
2回目:Hello World!
3回目:Hello World!
4回目:Hello World!
6回目:Hello World!
7回目:Hello World!

引数はbreakの視点になってみた構造です。
1つ目がswitch、2つ目がforなのでfor文も抜けたい場合は「break 2」と指定します。

continue

残りの処理をスキップし次のループ処理を実行します。
処理を見てみましょう。

<?php
for ( $i = 1; $i <= 10; $i++ ) {
    if ( $i % 2 == 0 ) {
        continue;
    }
    echo $i . "回目:Hello World!\n";
}

for文はいつもと変わらず10回より大きかったら処理が終了するループ文です。
その中にif文で$iを2で割った余りの値が0の場合、continue(スキップ)する処理を追加しました。
まずは出力結果を見てみましょう。

1回目:Hello World!
3回目:Hello World!
5回目:Hello World!
7回目:Hello World!
9回目:Hello World!

2の倍数はスキップされていることがわかります。
breakとの違い分かりましたか?continueはスキップされるだけなのでループ処理は続きます。

ではおさらいとしてcontinue⇒breakに変えてみましょう。

<?php
for ( $i = 1; $i <= 10; $i++ ) {
    if ( $i % 2 == 0 ) {
        break;
    }
    echo $i . "回目:Hello World!\n";
}
1回目:Hello World!

もうわかりますよね。そうです!2回目にきたときにループを抜けるので1回の出力のみになります。

breakと同様でcotinueにもオプション引数があります。
ネストしたループ構造を強制的にスキップすることができます。省略した場合は「continue 1」となります。

<?php
for ( $i = 1; $i <= 3; $i++ ) {
    for ( $j = 1; $j <= 10; $j++ ) {
        if ( $j == 2 ){
            continue 1; // 内側のfor文が対象
        } elseif ( $j == 5 ) {
            continue 2; // 外側のfor文が対象
        }
        echo  "i:" . $i . "、j:" . $j . "\n";
    }
}

このように多重ループになると複雑になってきますね!

「外側のループ iは3回までループ」「内側のループ jは10回までループ」といつも通りですね。
if文は$jが2の場合、残りの処理をスキップします。これも先ほどやりましたね。
$jが5の場合、「continue 2」となっているので6回以降の処理は全てスキップされます。そして外側のループ条件に戻ってきます。

i:1、j:1
i:1、j:3
i:1、j:4
i:2、j:1
i:2、j:3
i:2、j:4
i:3、j:1
i:3、j:3
i:3、j:4

出力結果をみればわかりやすいですね。
内側のループはjが2の時は出力がスキップされているので出力されていません。
さて$jが5の時ですね。jは10回までループさせる条件ですが、5の場合に「continue 2」としているので6回以降は実行されません。
これが「continue 1」と「continue 2」の違いです!

まとめ

いかがでしたか?ループが複雑になればなるほど混乱しますよね。。
今回は「while文」「for文」「foreach文」の繰り返し処理と処理を抜けたり、スキップする「break文」「continue文」をまとめました!

さて次回は関数(function)についてご紹介します。

最後までお読みいただきましてありがとうございました(^ω^)

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です