基本三構造

基本三構造とは

プログラムでは「順次処理」「条件分岐」「繰り返し」の3つの動きがあり、 基本三構造といいます。

  • 順次処理
  • 条件分岐
  • 繰り返し

順次処理

順次進行はソースコードを上から順に処理する構造で、プログラムの最も基本的な動きです。今までプログラミングした通り、上から順に「処理1」「処理2」とプログラムが記述されていたら、「処理1」「処理2」と処理されます。

条件分岐

条件分岐は「もし◯◯だったら」「そうでなければ」といった条件によって処理を分岐します。

  • 所持金が足りていれば購入、そうでなければ購入できない
  • もし移動距離が1km未満だったら徒歩、1km-5km未満だったら自転車、5km以上だったら電車

「true」「false」で判別

条件の結果「Yes」「No」と判別された場合、プログラムではboolean型のtrue、falseで分岐します。

if文

条件分岐の基礎となるのがif文です。if ( ) を記述し、カッコのなかに条件を記述します。

条件

if (条件)

処理

条件がtrueのときの処理を、{ } の中に記述します。

if (条件) {
    //trueのときの処理
}

if文で処理

所持金が価格以上だったら購入メッセージを表示します。

condition.php
<?php
//価格
$price = 200;
//所持金
$money = 100;
//所持金が価格以上だったら
if ($money >= $price) {
    $message = "お買い上げありがとうございました";
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   <h3>所持金</h3>
   <p><?= $money ?>円</p>
   <h3>価格</h3>
   <p><?= $price ?>円</p>
   <p><?= $message ?></p>
</body>
</html>

if else文

if else文は、条件がfalseだったときも処理できます。

if (条件) {
   //trueのときの処理
} else {
   //falseのときの処理
}

if else文で処理

所持金があれば購入、そうでなければ購入できないように分岐します。

condition.php
$price = 200;
$money = 100;
if ($money >= $price) {
    $message = "お買い上げありがとうございました";
} else {
    $message = "購入金額が足りません";
}

else if文

else if文は2つ以上の条件で処理することができます。

if (条件1) {
   //条件1が「true」だったときの処理
} else if (条件2) {
   //条件2が「true」だったときの処理
} else {
   //すべてfalseだったときの処理
}

else if文で処理

移動距離によって移動方法を変えます。

  • 5km以上:電車
  • 1km-5km未満:自転車
  • それ以外:徒歩
condition.php
$distance = 3;
$moving_method = "";
if ($distance < 1) {
	$moving_method = "徒歩";
} else if ($distance < 5) {
	$moving_method = "自転車";
} else {
	$moving_method = "電車";
}
$moving_message = "{$moving_method}で移動します。";

HTML部分

condition.php
<h2>距離</h2>
<p><?= $distance ?>km</p>
<h2>移動メッセージ</h2>
<p><?= $moving_message ?></p>

ネスト

ネストとは

同じ処理を繰り返するようなコードをネストといいます。例えば、if文をネストすると複雑な条件を処理できますが、プログラムが見づらくなります。

if (条件1) {
  //条件1が「true」だったときの処理
  if (条件2) {
     //条件2が「true」だったときの処理
  } else {
     //条件3が「false」だったときの処理
  }
} else {
  //条件1が「false」だったときの処理
}

ネストで処理

雨かどうかを「$is_rain」で判断し、外出しないという条件を付け加えてみました。

condition.php
$distance = 3;
$is_rain = true;
$moving_method = "";
if ($is_rain) {
    $moving_method = "家にいます";
} else {
    if ($distance < 1) {
        $moving_method = "徒歩";
    } else if ($distance < 5) {
        $moving_method = "自転車";
    } else {
        $moving_method = "電車";
    }
    $moving_message = "{$moving_method}で移動します。";
}

ネストはプログラムの欠陥?

if 文が連続してしまう分岐は、プログラムのアルゴリズムにどこか欠陥があります。if文は必要最低限で利用するようにしましょう。

else ifが連続

if ($year == 2000) {
	//
} else if ($year == 2001) {
	//
} else if ($year == 2002) {
	//
} else if ($year == 2003) {
	//
...
}

ifのネストが連続

if ($is_fine) {
	if ($is_morning) {
		if ($is_holiday) {
			//
		}
	}
}

論理演算子

論理演算子左と右を比べてTrue、Falseを判別する演算子です。

名称 演算子 比較 意味
論理積 AND && A && B A、B両方 True
論理和 OR || A || B A、Bどちらか True
論理否定 NOT ! !A Aでない

&&(AND)

&&はAND演算子で、どちらも条件が一致するか判別します。

A B A && B
1 1 1
1 0 0
0 1 0
0 0 0

||(OR)

|| はOR演算子で、どちらかの条件が一致するか判別します。

A B A || B
1 1 1
1 0 1
0 1 1
0 0 0

!(NOT)

!NOTで否定をします。

A !A
1 0
0 1

論理演算子で条件分岐

条件を以下のように修正してみましょう。

  • 自宅:距離が0(km)以下、または雨のとき
  • 自転車:1(km)以上かつ、5(km)未満
condition.php
$distance = 3;
$is_rain = true;
$moving_message = "";
//距離が0以下、または雨のとき
if ($distance <= 0 || $is_rain) {
    $moving_message = "家にいます";
} else {
    if ($distance < 1) {
        $moving_method = "徒歩";
    } else if ($distance >= 1 && $distance < 5) {
        $moving_method = "自転車";
    } else {
        $moving_method = "電車";
    }
    $moving_message = "{$moving_method}で移動します。";
}

コロン構文

if文とHTMLタグの問題

if文で条件分岐してHTML表示するとき、echoでHTMLタグと連結させて文字列を出力しますが、aタグの「href」プロパティは「 " 」(ダブルクォーテーション)で囲むため、コーディングが難しくなります。

HTMLタグを連結

pタグとaタグと変数を出力するには「 . 」文字を連結しますが、aリンクの「 " 」が混在するので「 ' 」(シングルクォーテーション)で記述します。

    <?php
    $user_name = "tokyo";
    if ($user_name) {
        echo '<p>ユーザ名:<a href="mypage.php">'. $user_name . '</a></p>';
    }
    ?>

「 " 」ををエスケープ

文字列に「 " 」を含む場合は、「 \ 」(バックスラッシュ)でエスケープすることもできます。

    <?php
    $user_name = "tokyo";
    if ($user_name) {
        echo "<p><a href=\"mypage.php\">ユーザ名:{$user_name}</a></p>";
    }
    ?>

endif文

このように、echoで「 " 」などの特殊文字や、複雑なHTMLタグの出力は現実的ではありません。そこでPHPでは、いくつかのコロン構文が用意されています。

endif文の基本

endif文は、if文のブロックスコープ「 { } 」ではなく「 : 」(コロン)で記述します。if(開始) と endif(終了)の間にHTMLを出力します。

<?php if (条件) : ?>
HTMLタグ
<?php endif ?>
  • if(開始)をphpタグで囲む
  • endif(終了)をphpタグで囲む
  • if と endif の間にHTMLタグを記述
  • 条件の行末は「 : 」(コロン)を記述

endif文の利用

endif文でHTMLタグを出力すると、通常のHTMLで記述できるのでとてもみやすくなります。

home.php
<?php
    $user_name = "tokyo";
?>

...
<?php if ($user_name) : ?>
    <p>ユーザ名:<a href="mypage.php"><?= $user_name ?></a></p>
<?php endif ?>
...

else、elseifのコロン構文

else と elseifもphpタグで囲み、「 : 」(コロン)で記述します。

<?php if (条件1) : ?>
HTMLタグ
<?php elseif (条件2) : ?>
HTMLタグ
<?php else (条件3) : ?>
HTMLタグ
<?php endif ?>
home.php
<?php
    $admin_name = "Admin";
    $user_name = "tokyo";
?>

...
    <nav>
        <a href="">Home</a>
        <?php if ($admin_name) : ?>
            <a href="">Admin Page</a>
        <?php elseif ($user_name) : ?>
            <a href="">My Page</a>
        <?php else : ?>
            <a href="">会員登録</a>
        <?php endif ?>
    </nav>
...

switch文

switch文のフロー

switch文はif文と同じように条件分岐できますが、変数の値をチェックするときに便利です。

switch文の基本

switch( ) のカッコの中に、比較する変数を設定します。

switch (変数) {
    //分岐処理
}

caseとbreakで分岐

caseで変数と値を比較して条件分岐します。どの条件にもあてはまらない場合、defaultで処理します。また、条件分岐の区切りにbreakがないと次の処理が実行されるので注意しましょう。

condition.php
switch (変数) {
  case 値1:
    処理1;
    break;
  case 値2:
    処理2;
    break;
  default:
    処理3;
    break;
}

switch文で処理

「月」「金」に「燃えるゴミ」、「水」に「燃えないゴミ」を取得してみます。

condition.php
$weekday = "月";
switch ($weekday) {
    case "月":
        $garbage = "燃えるゴミ";
        break;
    case "水":
        $garbage = "燃えないゴミ";
        break;
    default:
        $garbage = "回収なし";
        break;
}

HTML部分

condition.php
<h2>ゴミの日</h2> 
<p><?= $weekday ?>曜日</p>
<p><?= $garbage ?></p>

複数の case を利用した例

複数の条件を分岐するには、case を連続して記述します。「金」に「燃えるゴミ」になるように修正します。

condition.php
$weekday = '月';
switch ($weekday) {
    case "月":
    case "金":
        $garbage = "燃えるゴミ";
        break;
    case "水":
        $garbage = "燃えないゴミ";
        break;
    default:
        $garbage = "回収なし";
        break;
}

そのswitch文は必要か?

上記のswitch文はあまりよい処理方法でなく、caseが増えたらその都度プログラムを修正しなければいけません。これを解決するには、配列、オブジェクト、クラスといったロジックを使うと解決できます。

演習

問題1

価格、個数、所持金を任意の数で設定し、合計金額が所持金によって購入するメッセージを変えてみましょう。

問題2

今日の曜日を取得して、燃えるゴミ(月・金)、燃えないゴミ(水)を判別して表示してみましょう。

ヒント

曜日の判別は date() を使って曜日の番号を取得できます。ネットや書籍で調べてみましょう。

date('w');

PHP超入門