Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: destructor vs register_shutdown_function

I have a PHP class that creates a PNG image on the fly and sends it to browser. PHP manual says that I need to make sure that imagedestroy function is called at end to release the memory. Now, if I weren't using a class, I would have some code like this:

function shutdown_func() 
{
    global $img;
    if ($img)
        imagedestroy($img);
}
register_shutdown_function("shutdown_func");

However, I believe that appropriate place for my class would be to place a call to imagedestroy in class' destructor.

I failed to find out if destructors get called the same way shutdown functions does? For example, if execution stops when user presses the STOP button in browser.

Note: whatever you write in your answer, please point to some article or manual page (URL) that supports it.

like image 427
Milan Babuškov Avatar asked Oct 25 '08 18:10

Milan Babuškov


2 Answers

I just tested with Apache, PHP being used as Apache module. I created an endless loop like this:

<?php
class X
{
    function __destruct()
    {
        $fp = fopen("/var/www/htdocs/dtor.txt", "w+");
        fputs($fp, "Destroyed\n");
        fclose($fp);
    }
};

$obj = new X();
while (true) {
    // do nothing
}
?>

Here's what I found out:

  • pressing STOP button in Firefox does not stop this script
  • If I shut down Apache, destructor does not get called
  • It stops when it reaches PHP max_execution_time and destuctor does not get called

However, doing this:

<?php
function shutdown_func() {
    $fp = fopen("/var/www/htdocs/dtor.txt", "w+");
    fputs($fp, "Destroyed2\n");
    fclose($fp);
}
register_shutdown_function("shutdown_func");

while (true) {
    // do nothing
}
?>

shutdown_func gets called. So this means that class destuctor is not that good as shutdown functions.

like image 165
Milan Babuškov Avatar answered Oct 18 '22 11:10

Milan Babuškov


Based on the principle that you should finish what you start, I'd say the destructor is the correct place for the free call.

The destructor will be called when the object is disposed of, whereas a shutdown function will not be called until script execution finishes. As noted by Wolfie, these won't necessarily happen if you forcibly halt the server or the script, but at that time, the memory allocated by PHP will be freed anyway.

Also noted by Wolfie, PHP will free up script resources when the script closes, so if you're only instantiating one of these objects, then you probably wouldn't notice a massive difference. However, if you later do end up instantiating these things, or do so in a loop, then you probably don't want to have to worry about a sudden spike in memory usage, so for the sake of future sanity, I return to my original recommendation; put it in the destructor.

like image 34
Rob Avatar answered Oct 18 '22 10:10

Rob