【PHP】再帰処理を行うときはstatic変数が便利!




PHPではあまり使う機会が少ないstatic変数ですが、実は再帰処理を行うときに便利であることを知ってびっくりしました。これを知っていたら、前のゴミみたいな処理もマシにかけたのに…と思ったので、記事にまとめてみました。

目次

static変数とは?

static変数は直訳すると「静的な変数」です。ローカル関数スコープで利用しますが、重要な点は

  1. 最初に関数が呼び出されたときのみ初期化が行われる
  2. 2回目以降の関数実行では初期化されず、値が保持される

という2点です。

static変数ではない場合

<?php
function test()
{
  $count = 1;
  $count++;
  echo $count . PHP_EOL;
}

test(); // 2
test(); // 2

こちらの関数は、関数スコープで$countを1で初期化して、さらに1を足したものを出力しています。この変数$countは、関数が呼び出されるたびに1で初期化され、その後1を足されるので何度呼び出しても同じ2を出力し続けます。

static変数の場合

function s_test()
{
  static $count = 1;
  $count++;
  echo $count . PHP_EOL;
}

test(); // 2
test(); // 3

一方で、$countを静的変数として定義すると、初期化は最初に関数が実行されたのみ行われます。そして関数に紐付いて値が保存されていくので、呼び出すたびに$countの値は1ずつ増えていきます。

再帰関数でstatic変数を利用する

例えば、ある処理を再帰で三回行いたい場合を考えます。以下のコードは、実際にstatic変数を利用して三回の処理を行ったサンプルです。

<?php
function recursive($a)
{
  static $count = 1; //初期化は初回の呼び出し時だけ
  if ($count > 3) {
    echo $a . PHP_EOL;
    return;
  }
  $count++;
  $a++;
  return recursive($a);
}

recursive(10); // =>13;

static変数を利用しない場合、何周目の再帰かを情報として持たせようとすると、引数が増えるなど複雑になりがちです。そのため、static変数を上のようにうまく利用することによって、分かりやすく見通しの良いコードで書くことができます。

※static変数を使わなかった場合

<?php
function not_recursive($a, $count = 1)
{
  if ($count > 3) {
    echo $a . PHP_EOL;
    return;
  }
  $count++;
  $a++;
  return not_recursive($a, $count);
}

not_recursive(10); // =>13;