Clutch
Clutch

Reputation: 7600

__destruct visibility for PHP

Should the "visibility" for the __destruct() function be public or something else? I'm trying to write a standards doc for my group and this question came up.

Upvotes: 23

Views: 5640

Answers (2)

Dan Soap
Dan Soap

Reputation: 10248

In Addition to Mark Biek's answer:

The __destruct() function must be declared public. Otherwise, the function will not be executed on script shutdown:

Warning: Call to protected MyChild1::__destruct() from context '' during shutdown ignored in Unknown on line 0
Warning: Call to private MyChild2::__destruct() from context '' during shutdown ignored in Unknown on line 0

This may not be harmful, but rather unclean.

But the most important thing about this: If the destructor is declared private or protected, the runtime will throw a fatal error in the moment the garbage collector tries to free objects:

<?php
class MyParent
{
    private function __destruct()
    {
        echo 'Parent::__destruct';
    }
}

class MyChild extends MyParent
{
    private function __destruct()
    {
        echo 'Child::__destruct';
        parent::__destruct();
    }
}

$myChild = new MyChild();
$myChild = null;
$myChild = new MyChild();

?>

outputs

Fatal error: Call to private MyChild::__destruct() from context '' in D:\www\scratchbook\destruct.php on line 20

(Thanks to Mark Biek for the excellent example!)

Upvotes: 29

Mark Biek
Mark Biek

Reputation: 150749

I think it would need to be public in the case where a subclass needs to explicitly call the __destruct method of the parent class.

Something like this would throw an error:

<?php
class MyParent
{
    private function __destruct()
    {
        echo 'Parent::__destruct';
    }
}

class MyChild extends MyParent
{
    function __destruct()
    {
        echo 'Child::__destruct';
        parent::__destruct();
    }
}

$myChild = new MyChild();
?>

Upvotes: 10

Related Questions