2
When searching for references of good practices in PHP
for memory management I came across several intentions of how to use destructors.
I know the leading actor is Garbage Collector but this is not part of the scope of my question.
References:
- own Manual PHP
- among some of the community highlight this
- and a external reference
But my readings brought me questions which I could not find answers being them...
Doubts:
- the function
__destruct(){}
empty will remove any value associated with the class or it is necessary to specify these values in its scope? after instantiating the class by reference and before script termination what is the difference between using
NULL
andunset()
for example:<?php $refer = new MyClass(); $refer->hello(); // output: Hello World! $refer = NULL; // ou unset($refer); // mais blocos de código aqui...
according to Manual PHP class inheritance requires the class "daughter" to clarify the call
parent::__destruct()
in the destructor... but and in the case of extended classes that instantiate another class in its scope? When assigningNULL
or useunset()
before ending the script will force both destructors or it is necessary to explain each one? 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 to which the more I question myself: when using Opcache or other cache of bytecode (that keeps the compiled in memory) how is treated fução
__destruct()
in this case of cache use?
I know that there is no "right way" since this depends on the use case, the needs of the code and the approach to structure it but I seek a qualified understanding of it.
Thank you in advance.
Right bad, when using
__destruct()
should I wearunset()
in its scope referring to values contained in the class in the case of usingunset()
on the occasion before the end of the instruction block? And if you wanted to "release" an instantiated index before the end of the instruction block in one instantiated class within another (not extended) would you call both destructors or just one? And when using Opcache a destructor would be really useful?– Lauro Moraes
You should only use unset if you want the object to be destroyed before the end of the script execution. When destroying an object only one destructor is executed. It executes the parent destructor if it does not override the parent in the daughter class. That is, if he has a destroyer declared in the father and has not in the son, he executes that of the father. If he has a destroyer declared in the son, he executes that of the son. If you want to run both destructors, inside the son destructor call Parent:__destruct();
– Antonio Alexandre
Yes the focus of the question is to destroy the object before the end of the script execution. As for my inheritance, my doubt is not about bad inheritance, but if: By "forcing" the destroyer of class "A" he would also force the destroyer of class "B" instantiated in class "A" (note that there is no inheritance among classes). What’s the difference between using
NULL
andunset()
for this as well as if the use of Opcache does not counteract the use of destructors (since it saves in memory).– Lauro Moraes
"netraliza" in my previous comment was a wrong word ... it would be something like: the use of Opcache does not make the work of destructors be in vain?
– Lauro Moraes
Opcache makes the scripts to be saved in memory pro php not need to load them, transform them into bytecode and execute each request. The bytecode is already in the memory. Although I have not yet used Opcache, the functioning of destructors should remain the same - My understanding is that the bytecode of the file in memory does not interfere with the variables during the execution of the script.
– Antonio Alexandre
Reference to start using Opcache: http://stackoverflow.com/questions/17224798/how-to-use-php-opcache
– Antonio Alexandre