基本三構造
基本三構造とは
プログラムでは「順次処理」「条件分岐」「繰り返し」の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');