What is constructor and destructor in php?

Constructor

__construct[mixed ...$values = ""]: void

PHP allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.

Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct[] within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method [if it was not declared as private].

Example #1 Constructors in inheritance



This will output:

Destroying: Foo 3
Destroying: Foo 4
End of script
Destroying: Foo 1
Destroying: Foo 2

But if we uncomment the gc_collect_cycles[]; function call in the middle of the script, we get:

Destroying: Foo 2
Destroying: Foo 1
Destroying: Foo 3
Destroying: Foo 4
End of script

As may be desired.

NOTE: calling gc_collect_cycles[] does have a speed overhead, so only use it if you feel you need to.

domger at freenet dot de

5 years ago

The __destruct magic method must be public.

public function __destruct[]
{
    ;
}

The method will automatically be called externally to the instance.  Declaring __destruct as protected or private will result in a warning and the magic method will not be called.

Note: In PHP 5.3.10 i saw strange side effects while some Destructors were declared as protected.

mmulej at gmail dot com

6 months ago

* I can't edit my previous note to elaborate on modifiers. Please excuse me.*

If both parent and child classes have a method with the same name defined, and it is called in parent's constructor, using `parent::__construct[]` will call the method in the child.



In this example both A::method and C::method are public.

You may change A::method to protected, and C::method to protected or public and it will still work the same.

If however you set A::method as private, it doesn't matter whether C::method is private, protected or public. Both $b and $c will echo 'A'.

iwwp at outlook dot com

2 years ago

To better understand the __destrust method:

class A {
    protected $id;

    public function __construct[$id]
    {
        $this->id = $id;
        echo "construct {$this->id}\n";
    }

    public function __destruct[]
    {
        echo "destruct {$this->id}\n";
    }
}

$a = new A[1];
echo "-------------\n";
$aa = new A[2];
echo "=============\n";

The output content:

construct 1
-------------
construct 2
=============
destruct 2
destruct 1

spleen

13 years ago

It's always the easy things that get you -

Being new to OOP, it took me quite a while to figure out that there are TWO underscores in front of the word __construct.

It is __construct
Not _construct

Extremely obvious once you figure it out, but it can be sooo frustrating until you do.

I spent quite a bit of needless time debugging working code.

I even thought about it a few times, thinking it looked a little long in the examples, but at the time that just seemed silly[always thinking "oh somebody would have made that clear if it weren't just a regular underscore..."]

All the manuals I looked at, all the tuturials I read, all the examples I browsed through  - not once did anybody mention this!

[please don't tell me it's explained somewhere on this page and I just missed it,  you'll only add to my pain.]

I hope this helps somebody else!

prieler at abm dot at

15 years ago

i have written a quick example about the order of destructors and shutdown functions in php 5.2.1:



this will output:
shutdown: a: global 1
shutdown: b: func 1
shutdown: c: func 2
shutdown: d: global 2
destruct: b: func 1
destruct: c: func 2
destruct: d: global 2
destruct: a: global 1

conclusions:
destructors are always called on script end.
destructors are called in order of their "context": first functions, then global objects
objects in function context are deleted in order as they are set [older objects first].
objects in global context are deleted in reverse order [older objects last]

shutdown functions are called before the destructors.
shutdown functions are called in there "register" order. ;]

regards, J

Per Persson

10 years ago

As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.

For example:


Without the $nonset->foo[]; line, Before and After will both be printed, but with the line neither will be printed.

One can however register the destructor or another method as a shutdown function:

Now Before will be printed, but not After, so you can see that a shutdown occurred after Before.

Yousef Ismaeil cliprz[At]gmail[Dot]com

9 years ago



The Mobile class is stratup.

I have a iPhone version 5 my device color is : Black

Dumpping Mobile::deviceName to make sure its removed, Olay :
string 'Removed' [length=7]

The Mobile class is shutdown.

Jonathon Hibbard

12 years ago

Please be aware of when using __destruct[] in which you are unsetting variables...

Consider the following code:


The above will result in an error:
Notice: Undefined property: my_class::$error_reporting in my_class.php on line 10

It appears as though the variable will be unset BEFORE it actually can execute the if statement.  Removing the unset will fix this.  It's not needed anyways as PHP will release everything anyways, but just in case you run across this, you know why ;]

bolshun at mail dot ru

14 years ago

Ensuring that instance of some class will be available in destructor of some other class is easy: just keep a reference to that instance in this other class.

david at synatree dot com

14 years ago

When a script is in the process of die[]ing, you can't count on the order in which __destruct[] will be called.

For a script I have been working on, I wanted to do transparent low-level encryption of any outgoing data.  To accomplish this, I used a global singleton class configured like this:

class EncryptedComms
{
    private $C;
    private $objs = array[];
    private static $_me;

        public static function destroyAfter[&$obj]
    {
        self::getInstance[]->objs[] =& $obj;
        /*
            Hopefully by forcing a reference to another object to exist
            inside this class, the referenced object will need to be destroyed
            before garbage collection can occur on this object.  This will force
            this object's destruct method to be fired AFTER the destructors of
            all the objects referenced here.
        */
    }
    public function __construct[$key]
    {
            $this->C = new SimpleCrypt[$key];
            ob_start[array[$this,'getBuffer']];
    }
    public static function &getInstance[$key=NULL]
    {
        if[!self::$_me && $key]
            self::$_me = new EncryptedComms[$key];
        else
            return self::$_me;
    }

        public function __destruct[]
    {
        ob_end_flush[];
    }

        public function getBuffer[$str]
    {
        return $this->C->encrypt[$str];
    }

}

In this example, I tried to register other objects to always be destroyed just before this object.  Like this:

class A
{

public function __construct[]
{
     EncryptedComms::destroyAfter[$this];
}
}

One would think that the references to the objects contained in the singleton would be destroyed first, but this is not the case.  In fact, this won't work even if you reverse the paradigm and store a reference to EncryptedComms in every object you'd like to be destroyed before it.

In short, when a script die[]s, there doesn't seem to be any way to predict the order in which the destructors will fire.

ziggy at start dot dust

1 month ago

Please note that constructor argument promotion is kind of half-baked [at least as of 8.1 and it does not look to be changed in 8.2] and you are not allowed to reuse promoted argument with other promoted arguments. For example having "old style" constructor:



you will not be able to use argument promotion like this:



nor



as in both cases you will face "PHP Fatal error:  Constant expression contains invalid operations".

Reza Mahjourian

16 years ago

Peter has suggested using static methods to compensate for unavailability of multiple constructors in PHP.  This works fine for most purposes, but if you have a class hierarchy and want to delegate parts of initialization to the parent class, you can no longer use this scheme.  It is because unlike constructors, in a static method you need to do the instantiation yourself.  So if you call the parent static method, you will get an object of parent type which you can't continue to initialize with derived class fields.

Imagine you have an Employee class and a derived HourlyEmployee class and you want to be able to construct these objects out of some XML input too.

Chủ Đề