LoginSignup
0
0

More than 5 years have passed since last update.

PeclのWeakRef

Last updated at Posted at 2013-04-20
unsetしても参照が残ってしまう
Satou.php
class Satou {
    private $d;
    public function setD($d) {
        $this->d = $d;
    }
    public function __destruct() {
        echo "Destroy!\n";
    }
}
RefTest1.php
class RefTest1 {
    private $satou;
    public function setSatou($satou) {
        $this->satou = $satou;
    }
    public function printSatou() {
        var_dump($this->satou);
    }
}

$satou = new Satou();
$satou->setD("bbbb");

$t = new RefTest1();
$t->setSatou($satou);
$t->printSatou();

unset($satou);

$t->printSatou();
結果
$ php RefTest1.php
object(Satou)#1 (1) {
  ["d":"Satou":private]=>
  string(4) "bbbb"
}
object(Satou)#1 (1) {
  ["d":"Satou":private]=>
  string(4) "bbbb"
}

当然ガベージコレクションの対象にはならない。
リークの危険性をはらむ。
そこで、Peclで提供されているWeakRefを使ってみる。

RefTest2.php
class RefTest2 {
    private $obj;
    public function setWeakRefObj($obj) {
        $this->obj = $obj;
    }
    public function printWeakRefObj() {
        var_dump($this->obj->get());
    }
}
$satou = new Satou();
$satou->setD("aaaa");
$ref = new \WeakRef($satou);

$t = new RefTest2();
$t->setWeakRefObj($ref);
$t->printWeakRefObj();

unset($satou);

$t->printWeakRefObj();
結果
$ php RefTest2.php
object(Satou)#1 (1) {
  ["d":"Satou":private]=>
  string(4) "aaaa"
}
Destroy
NULL

unsetを呼び出したタイミングでdeconstructorが呼び出され、
2回目のprint時に、RefTest2のプロパティには参照が残っていない状態になる。


このように、参照を渡したいが、オブジェクトのライフサイクルを共有したい場合には、このWeakRefが使える。
現在Versionが0.2.2で、まだまだメジャーバージョンには程遠いが、例のような使い方程度なら全く問題ないように思える。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0