本篇文章主要給大家介紹PHP 析構方法 __destruct() 不觸發的兩個解決辦法。
有時候在 PHP 里類循環引用時,會導致 __destruct() 不觸發的問題,先上問題代碼:
- <?php
- class Proxy
- {
- private $object;
- public function __construct($object)
- {
- $this->object = $object;
- }
- public function __destruct()
- {
- var_dump('__destruct:Proxy');
- }
- }
- class Test
- {
- private $proxy;
- public function __construct()
- {
- $this->proxy = new Proxy($this);
- }
- public function __destruct()
- {
- var_dump('__destruct:Test');
- }
- }
- $test = new Test;
- unset($test);
- echo 'no __destruct, wait 3s', PHP_EOL;
- sleep(3);
- echo '__destruct now:', PHP_EOL;
如上代碼,運行unset($test)時,不會觸發__destruct(),因為有了循環引用。
再看下面的解決方法1的代碼:
- <?php
- class Proxy
- {
- private $object;
- public function __construct($object)
- {
- $this->object = $object;
- }
- public function __destruct()
- {
- var_dump('__destruct:Proxy');
- }
- }
- class Test
- {
- private $proxy;
- public function __construct()
- {
- $this->proxy = new Proxy($this);
- }
- public function __destruct()
- {
- var_dump('__destruct:Test');
- }
- public function close()
- {
- $this->proxy = null;
- }
- }
- $test = new Test;
- $test->close();
- echo '__destruct now:', PHP_EOL;
- unset($test);
- sleep(3);
- echo 'no operation', PHP_EOL;
上面的代碼,在unset之前,將Test類中的proxy設為null,然后再unset,就可以觸發__destruct()了。
當然,你也可以手動gc(解決方法2):
- <?php
- class Proxy
- {
- private $object;
- public function __construct($object)
- {
- $this->object = $object;
- }
- public function __destruct()
- {
- var_dump('__destruct:Proxy');
- }
- }
- class Test
- {
- private $proxy;
- public function __construct()
- {
- $this->proxy = new Proxy($this);
- }
- public function __destruct()
- {
- var_dump('__destruct:Test');
- }
- }
- $test = new Test;
- unset($test);
- echo '__destruct now:', PHP_EOL;
- gc_collect_cycles();
- sleep(3);
- echo 'no operation', PHP_EOL;
希望對需要的朋友有所幫助!
新聞熱點
疑難解答