Maison  >  Article  >  développement back-end  >  Deux solutions pour la méthode de destructeur PHP __destruct() qui ne se déclenche pas

Deux solutions pour la méthode de destructeur PHP __destruct() qui ne se déclenche pas

藏色散人
藏色散人avant
2019-04-24 11:22:373435parcourir

Cet article présente principalement deux solutions au problème selon lequel la méthode du destructeur PHP __destruct() n'est pas déclenchée.

Parfois, lorsqu'une classe est référencée de manière cyclique en PHP, cela provoque le problème que __destruct() n'est pas déclenchée. Examinons d'abord le code du problème :

<?php
class Proxy
{
    private $object;
 
    public function __construct($object)
    {
        $this->object = $object;
    }
 
    public function __destruct()
    {
        var_dump(&#39;__destruct:Proxy&#39;);
    }
}
 
class Test
{
    private $proxy;
 
    public function __construct()
    {
        $this->proxy = new Proxy($this);
    }
 
    public function __destruct()
    {
        var_dump(&#39;__destruct:Test&#39;);
    }
}
 
$test = new Test;
unset($test);
 
echo &#39;no __destruct, wait 3s&#39;, PHP_EOL;
 
sleep(3);
 
echo &#39;__destruct now:&#39;, PHP_EOL;

Comme le code ci-dessus, run unset($test) , __destruct() ne sera pas déclenché car il existe une référence circulaire.

Regardez le code de la solution 1 ci-dessous :

<?php
class Proxy
{
    private $object;
 
    public function __construct($object)
    {
        $this->object = $object;
    }
 
    public function __destruct()
    {
        var_dump(&#39;__destruct:Proxy&#39;);
    }
}
 
class Test
{
    private $proxy;
 
    public function __construct()
    {
        $this->proxy = new Proxy($this);
    }
 
    public function __destruct()
    {
        var_dump(&#39;__destruct:Test&#39;);
    }
 
    public function close()
    {
        $this->proxy = null;
    }
}
 
$test = new Test;
$test->close();
 
echo &#39;__destruct now:&#39;, PHP_EOL;
 
unset($test);
 
sleep(3);
 
echo &#39;no operation&#39;, PHP_EOL;

Le code ci-dessus, avant de le désactiver, définissez le proxy dans la classe Test sur null, puis désactivez-le à nouveau, il peut être déclenché __destruct().

Bien sûr, vous pouvez également gc manuellement (solution 2) :

<?php
class Proxy
{
    private $object;
 
    public function __construct($object)
    {
        $this->object = $object;
    }
 
    public function __destruct()
    {
        var_dump(&#39;__destruct:Proxy&#39;);
    }
}
 
class Test
{
    private $proxy;
 
    public function __construct()
    {
        $this->proxy = new Proxy($this);
    }
 
    public function __destruct()
    {
        var_dump(&#39;__destruct:Test&#39;);
    }
}
 
$test = new Test;
unset($test);
 
echo &#39;__destruct now:&#39;, PHP_EOL;
gc_collect_cycles();
 
sleep(3);
 
echo &#39;no operation&#39;, PHP_EOL;

J'espère que cela sera utile aux amis dans le besoin !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer