PHP

初心者向け。覚えておきたい 「ガード節」という書き方。

最初に

何においてもそうですが、どんな時にても当てはまるやり方というものではありません。ケースによっては逆に読みづらくバグを生みやすくなる場合もあります。コードを最適化するときの手段の一つとして理解していただければと思います。

ガード節とは

処理の対象外とする条件を関数やループの先頭に集め、早めに return や continue/break で抜ける方法です。ネストを減らし異常系と正常系の処理がわかりやすくなるメリットがあります。

具体例

もちろん実際のコードはもっと複雑で長くなりますが、仕事場で以下のようなコードに結構出くわします。

function check($a, $b, $C) {
  if (is_null($a)) {
    $result = 0;
  } else {
    if (is_null($b) {
      $result = 0;
    } else {
      if (is_null($c) {
        $result = 0;
      } else {
        $result = 1;
      }
    }
  }
  return $result;
}

おそらく、\$aがNULLの場合は返却値に0を入れ、そうでなければ\$bの値を確認する。その\$bがNULLの場合は..... と思考のままにプログラムを行い、その後に見直しを行なわなかったらこうなるのでしょうか?正常系コードがネストの深い位置にあり、他の人が処理を追う時に苦労します。

これを「ガード節」を使い書き換えた場合、以下のようになります。

function check($a, $b, $c) {
  if (is_null($a)) return 0;
  if (is_null($b)) return 0;
  if (is_null($c)) return 0;

  return 1;
}

関数の先頭に異常系となる条件を集め、即座にreturnすることで、正常系コードのネストが増えることを防いでいます。
なお、forループで使う場合は以下のように Continue をつかいます。

$result = PDOStatement::fetchAll();
foreach ($result as $rows) {
  if ($rows['kind'] != 2) continue; // XXXの場合

  // 正常系の処理
}

これを以下のようにガード節を使わずに書いた場合は以下のようになります。

$result = PDOStatement::fetchAll();
foreach ($result as $row) {
  if ($row['kind'] == 2) {
    // 正常系の処理

  }
}

悪くはありませんが、ネストが増える事と、kindが0と1の場合の処理を追うのにif文の最後まで読む必要がある点を考慮するとガード節のほうがより良いコードだと考えます。