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

PHPでインスタンスを作成するメソッドをチェーンした場合のオブジェクトの寿命

PHP

以下のコードを実行するとどのような結果になるでしょうか?

<?php
class XXX
{
	private $_id;

	public function __construct($id)
	{
		$this->_id = $id;
		echo "ctor $this->_id\n";
	}

	public function __destruct()
	{
		echo "dtor $this->_id\n";
	}

	public function func($id)
	{
		return new self($id);
	}

	public static function create($id)
	{
		return new self($id);
	}
}

(new XXX(1))->func(2)->func(3)->func(4);


↓のように表示されました(PHP 5.4.6)。

ctor 1
ctor 2
dtor 1
ctor 3
dtor 2
ctor 4
dtor 4
dtor 3


てっきり↓のようになると思っていたのですが・・・「new XXX(1)」で作成したインスタンスは「->func(2)」の呼び出し後に削除され、「->func(2)」が作成したインスタンスは「->func(3)」の呼び出し後に削除され・・・という風になるようです。

ctor 1
ctor 2
ctor 3
ctor 4
dtor 4
dtor 3
dtor 2
dtor 1


デストラクタで何かするクラスを作るときには気をつけなければならないかもしれません*1


C++ で↓のようにすると後者の順番になるので php の動作には違和感があります。

XXX(1).func(2).func(3).func(4);

*1:PHP 5.5 で finally が導入されるならデストラクタとか使わないほうがいいのかも?