3

私はこの解決策を見つけましたが、おそらくもっと良い解決策があると思います。それについてどう思いますか?

class A
{
        #A self-reference
        private $_a;
        #Construcotr makes a self-reference
        public function __construct()
        {
                $this->_a = $this;
        }
        #Some other functions
        public function hello()
        {
                echo 'Hello, world!' . PHP_EOL;
        }
        #Function to destruct just this object, not its parent
        public function myDestruct()
        {
                unset($this->_a);
                var_dump($this);
        }
}

class AProxy
{
        #The proxied object
        public $_a;
        #The constructor has to be rewritten
        public function __construct()
        {
                $this->_a = new A();
        }
        #The destructor
        public function __destruct()
        {
                $this->_a->myDestruct();
                unset($this->_a);
                var_dump($this);
        }
        #Some other functions
        public function __call($fct, $args)
        {
                call_user_func(array($this->_a, $fct), $args);
        }
}

echo 'START' . PHP_EOL;
#Use class AProxy instead of class A
$a = new AProxy();

$a->hello();

unset($a);

#Otherwize you need to trigger the garbage collector yourself
echo 'COLLECT' . PHP_EOL;
gc_collect_cycles();

echo 'END' . PHP_EOL;

クラス A をそのまま使用すると、A のプロパティの 1 つに自己参照があるため、設定解除は機能しません。

この場合、ガベージ コレクターを手動で呼び出す必要があります。

私が見つけた解決策は、A で myDestructor という名前の特別な関数を呼び出す AProxy と呼ばれるプロキシ クラスを使用することです。この関数は、A クラスのみを破棄し、その親は破棄しません。

次に、AProxy のデストラクタは、A のインスタンスで myDestructor を呼び出します。

AProxy を A クラスに似せるために、__call 関数を再実装しました (プロパティのセッターとゲッターもオーバーロードされる場合があります)。

それよりも良い解決策はありますか?

4

0 に答える 0