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

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

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

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

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

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

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

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

Tags: PHP析构方法 __destruct

分享到: