読者です 読者をやめる 読者になる 読者になる

クロージャーの static 変数はインスタンス変数なのか?

次のコードを実行すると、

<?php
$func = function () {
    static $val;
    if (!isset($val))
    {
        $val = 0;
    }
    return ++$val;
};

for ($i=0; $i<5; $i++)
{
    var_dump($func());
}

次のようになります。至って妥当な結果だと思います。

int(1)
int(2)
int(3)
int(4)
int(5)

次のコードだと、

<?php
for ($i=0; $i<5; $i++)
{
    $func = function () {
        static $val;
        if (!isset($val))
        {
            $val = 0;
        }
        return ++$val;
    };
    var_dump($func());
}

次のようになります。static でもクロージャーのインスタンスごとの変数になっています。

int(1)
int(1)
int(1)
int(1)
int(1)

次のコードだと、

<?php
$func = function () {
    static $val;
    if (!isset($val))
    {
        $val = 0;
    }
    return ++$val;
};

var_dump($func());

$func2 = clone $func;

var_dump($func());
var_dump($func2());

次のようになります。static 変数も close されているような動きです。

$ php z.php
int(1)
int(2)
int(2)

static 変数を含むクロージャーを var_dump してみると、

<?php
$func = function () {
    static $val;
};

var_dump($func);

クロージャー内部の static 変数がまるでクロージャーのインスタンス変数であるかのように表示されます。

class Closure#1 (1) {
  public $static =>
  array(1) {
    'val' =>
    NULL
  }
}