当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP析构方法 __destruct() 不触发的两个解决办法

发布:smiling 来源: PHP粉丝网  添加日期:2020-03-31 18:17:29 浏览: 评论:0 

本篇文章主要给大家介绍PHP 析构方法 __destruct() 不触发的两个解决办法。

有时候在 PHP 里类循环引用时,会导致 __destruct() 不触发的问题,先上问题代码:

  1. <?php 
  2.  
  3. class Proxy 
  4.  
  5. { 
  6.  
  7.     private $object; 
  8.  
  9.    
  10.  
  11.     public function __construct($object) 
  12.  
  13.     { 
  14.  
  15.         $this->object = $object; 
  16.  
  17.     } 
  18.  
  19.    
  20.  
  21.     public function __destruct() 
  22.  
  23.     { 
  24.  
  25.         var_dump('__destruct:Proxy'); 
  26.  
  27.     } 
  28.  
  29. } 
  30.  
  31.    
  32.  
  33. class Test 
  34.  
  35. { 
  36.  
  37.     private $proxy; 
  38.  
  39.    
  40.  
  41.     public function __construct() 
  42.  
  43.     { 
  44.  
  45.         $this->proxy = new Proxy($this); 
  46.  
  47.     } 
  48.  
  49.    
  50.  
  51.     public function __destruct() 
  52.  
  53.     { 
  54.  
  55.         var_dump('__destruct:Test'); 
  56.  
  57.     } 
  58.  
  59. } 
  60.  
  61.    
  62.  
  63. $test = new Test; 
  64.  
  65. unset($test); 
  66.  
  67.    
  68.  
  69. echo 'no __destruct, wait 3s', PHP_EOL; 
  70.  
  71.    
  72.  
  73. sleep(3); 
  74.  
  75.    
  76.  
  77. echo '__destruct now:', PHP_EOL; 

如上代码,运行unset($test)时,不会触发__destruct(),因为有了循环引用。

再看下面的解决方法1的代码:

  1. <?php 
  2.  
  3. class Proxy 
  4.  
  5. { 
  6.  
  7.     private $object; 
  8.  
  9.    
  10.  
  11.     public function __construct($object) 
  12.  
  13.     { 
  14.  
  15.         $this->object = $object; 
  16.  
  17.     } 
  18.  
  19.    
  20.  
  21.     public function __destruct() 
  22.  
  23.     { 
  24.  
  25.         var_dump('__destruct:Proxy'); 
  26.  
  27.     } 
  28.  
  29. } 
  30.  
  31.    
  32.  
  33. class Test 
  34.  
  35. { 
  36.  
  37.     private $proxy; 
  38.  
  39.    
  40.  
  41.     public function __construct() 
  42.  
  43.     { 
  44.  
  45.         $this->proxy = new Proxy($this); 
  46.  
  47.     } 
  48.  
  49.    
  50.  
  51.     public function __destruct() 
  52.  
  53.     { 
  54.  
  55.         var_dump('__destruct:Test'); 
  56.  
  57.     } 
  58.  
  59.    
  60.  
  61.     public function close() 
  62.  
  63.     { 
  64.  
  65.         $this->proxy = null; 
  66.  
  67.     } 
  68.  
  69. } 
  70.  
  71.    
  72.  
  73. $test = new Test; 
  74.  
  75. $test->close(); 
  76.  
  77.    
  78.  
  79. echo '__destruct now:', PHP_EOL; 
  80.  
  81.    
  82.  
  83. unset($test); 
  84.  
  85.    
  86.  
  87. sleep(3); 
  88.  
  89.    
  90.  
  91. echo 'no operation', PHP_EOL; 

上面的代码,在unset之前,将Test类中的proxy设为null,然后再unset,就可以触发__destruct()了。

当然,你也可以手动gc(解决方法2):

  1. <?php 
  2.  
  3. class Proxy 
  4.  
  5. { 
  6.  
  7.     private $object; 
  8.  
  9.    
  10.  
  11.     public function __construct($object) 
  12.  
  13.     { 
  14.  
  15.         $this->object = $object; 
  16.  
  17.     } 
  18.  
  19.    
  20.  
  21.     public function __destruct() 
  22.  
  23.     { 
  24.  
  25.         var_dump('__destruct:Proxy'); 
  26.  
  27.     } 
  28.  
  29. } 
  30.  
  31.    
  32.  
  33. class Test 
  34.  
  35. { 
  36.  
  37.     private $proxy; 
  38.  
  39.    
  40.  
  41.     public function __construct() 
  42.  
  43.     { 
  44.  
  45.         $this->proxy = new Proxy($this); 
  46.  
  47.     } 
  48.  
  49.    
  50.  
  51.     public function __destruct() 
  52.  
  53.     { 
  54.  
  55.         var_dump('__destruct:Test'); 
  56.  
  57.     } 
  58.  
  59. } 
  60.  
  61. $test = new Test; 
  62.  
  63. unset($test); 
  64.  
  65. echo '__destruct now:', PHP_EOL; 
  66.  
  67. gc_collect_cycles(); 
  68.  
  69. sleep(3); 
  70.  
  71. echo 'no operation', PHP_EOL; 

希望对需要的朋友有所帮助!

Tags: PHP析构方法 __destruct

分享到: