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で、まだまだメジャーバージョンには程遠いが、例のような使い方程度なら全く問題ないように思える。