What is the "correct way" to use destructors in PHP

2

When looking for references to good practices in PHP for memory management, I came across a number of ways to use destructors .

I know the main actor is the Garbage Collector but this one is not Garbage Collector is part of the scope of my question.

References:

But my readings bring me doubts which I did not find answers being them ...

Questions:

  • will the empty co_de function remove any value associated with the class or do you need to explicitly state these values in your scope?
  • After instantiating the class by reference and before the script closes the difference between using __destruct(){} and NULL for example:

    <?php
        $refer = new MyClass();
        $refer->hello(); // output: Hello World!
    
        $refer = NULL; // ou unset($refer);
    
        // mais blocos de código aqui...
    
  • According to PHP Manual class inheritance requires the "daughter" class to explicitly call unset() in destructor ... bad and in case of non-extended classes that instantiate another class in its scope? When assigning parent::__destruct() or using NULL before the script closes will you force both destructors or need to be explicit? Example:

    <?php
        /**
        class Core
        {
             public function __construct(){}
    
             public function session($start=true)
             {
                 if ( !$start  ) {
                      if ( isset($_SESSION) ) {
                           session_destroy();
                           return true;
                      }
                 }
                 session_start();
             }
    
             public function language()
             {
                 if ( isset($_SESSION) ) {
                      $_SESSION['language'] = 'pt-BR';
                 }
             }
    
             public function layoutEngine()
             {
                 return new HandlerUI(); // outra classe
             }
    
             function __destruct(){
                 #
             }
        }
    
        class HandlerUI
        {
             function __construct()
             {
                 return $this;
             }
    
             public function Header()
             {
                 return "<head><title>Hello World</title></head>";
             }
    
             public function NavBar()
             {
                 return "<nav>This is navbar</nav>";
             }
    
             public function Drawer()
             {
                 return "<div class='drawer-container'></div>";
             }
    
             public function Footer()
             {
                 return "<footer>I am Footer</footer?";
             }
    
             public function JavaScript()
             {
                 return "<script type='text/javascript'>console.log('hola que tal');</script>";
             }
    
             function __destruct(){
                 #
             }
        }
        */
    
        // caso de uso:
        $app = new Core()
    
        $app->session();
        $app->language();
    
        $layout = $app->layoutEngine();
    
        unset($app); // ou $app = NULL;
    ?>
    <!DOCTYPE html>
    <html lang="<?php echo $_SESSION['language'];?>">
    <?php
        $layout->Header();
    ?>
    <body id="body">
        <!-- CONTAINER -->
        <section class="default">
            <?php
                // navbar
                $layout->Navbar();
                // drawer
                $layout->Drawer();
            ?>
    
            <!-- CENTRAL BLOCK -->
            <section id="central-block"></section>
            <?php
                //
                $layout->Footer();
            ?>
        </section>
        <?php
            //
            $layout->JavaScript();
    
            unset($layout); // ou $layout = NULL;
    
            // mais blocos de código aqui...
        ?>
    </body>
    </html>
    
  • and I wonder more : using OPcache or another bytecode cache (which stores in compiled memory) how the unset() fuction is handled in this cache usage case?

I know that there is no "right way" since this depends on the use case, the needs of the code and the approach in structuring it, but I am looking for a qualified understanding of it.

Thank you in advance.

    
asked by anonymous 08.03.2017 / 10:17

1 answer

2

The __destruct method is used to perform a last action before the object ceases to exist.

One use that can be done with it if you build a framework is to put a generic Controller calling a view of the same name of the Controller at the end of execution. When other controllers extend this generic controller they will all have this functionality to call the appropriate view automatically at the end of execution.

Code sample using __construct and __destruct:

<?php

class Teste
{
    private $nome;

    function __construct($nome)
    {
        echo 'O objeto foi construído.<br>';
        $this->nome = $nome;
    }

    function saudacao()
    {
        return 'Olá ' . $this->nome . '! <br>'; 
    }

    function __destruct()
    {
        echo 'O objeto não existirá mais após essa mensagem.';
    }   

}


$teste = new Teste('Lauro');

echo $teste->saudacao();


?>

Output generated by running the above script:

O objeto foi construído.
Olá Lauro!
O objeto não existirá mais após essa mensagem.

Note: PHP clears all memory variables at the end of script execution. Then at the end of the script, when removing the object it executes destruct automatically. But if the object were destroyed with unset destruct would be called the same way, just before the script finishes completely.

There is no need to declare __construct or __destruct if you do not use them.

    
08.03.2017 / 10:46