Приглашаем посетить
Html (html.find-info.ru)

Section 8.10.  Constructors and Destructors

Previous
Table of Contents
Next

8.10. Constructors and Destructors

If you think back to the example where each dog had a DogTag object in it, this led to code like the following:

    $poppy = new Poodle;
    $poppy->Name = "Poppy";
    $poppy->DogTag = new DogTag;
    $poppy->DogTag->Words = "If you find me, call 555-1234";

Using that method, if we had other objects inside each Poodle object, we would need to create the Poodle plus all its other associated objects by hand.

Another way to do this is to use constructors . A constructor is a special method you add to classes that is called by PHP whenever you create an instance of the class. For example:

    class DogTag {
            public $Words;
    }

    class Dog {
            public $Name;
            public $DogTag;

            public function bark( ) {
                    print "Woof!\n";
            }

            public function _ _construct($DogName) {
                    print "Creating a Dog: $DogName\n";
                    $this->Name = $DogName;
                    $this->DogTag = new DogTag;
                    $this->DogTag->Words = "My name is $DogName. If you find me,
                                                       please call 555-1234";
            }
    }

    class Poodle extends Dog {
            public function bark( ) {
                    print "Yip!\n";
            }
    }

    $poppy = new Poodle("Poppy");
    print $poppy->DogTag->Words . "\n";

Note the _ _construct( ) method in the Dog class, which takes one variablethat is our constructor. Whenever we instantiate a Poodle object, PHP calls the relevant constructor.

There are three other important things to note:

  • The constructor is not in the Poodle class, it's in the Dog class. When PHP looks for a constructor in Poodle, and fails to find one there, it goes to its parent class (where Poodle inherited from). If it fails to find one there, it goes up again, and up again, ad infinitum, until it reaches the top of the class structure. As the Dog class is the top of our class structure, PHP does not have far to go.

  • PHP only ever calls one constructor for you. If you have several constructors in a class structure, PHP will only call the first one it finds.

  • The _ _construct( ) method is marked public, which is not by accident. If you don't mark the constructor as public, you can instantiate objects of a class only from within the class itself, which is almost an oxymoron. If you make this private, you need to use a static method call, which is discussed later in this chapter.

8.10.1. Parent Constructors

Take a look at this code:

    class Poodle extends Dog {
            public function bark( ) {
                    print "Yip!\n";
            }

            public function _ _construct($DogName) {
                    print "Creating a poodle\n";
            }
    }

If you replace the original Poodle definition with this new one and try running the script again, you will get the error message: "trying to get property of non-object" on the line where we have print $poppy->DogTag->Words. This is because DogTag is defined as being an instance of our DogTag class only in the Dog class constructor, and, as PHP will only ever call one constructor for us, the Dog class constructor is not called because PHP finds the Poodle constructor first.

The fact that PHP always calls the "nearest" constructorthat is, if there is no child constructor, it will call the parent constructor and not the grandparent constructormeans that we need to call the parent constructor ourselves. We can do this by using the special method call parent::_ _construct( ). The "parent" part means "get the parent of this object, and use it," and the _ _construct( ) part means "Call the construct method." So the whole line means "Get the parent of this object and then call its constructor."

The call to the parent's _ _construct( ) is just a normal method call, and the dog constructor needs a dog name as its parameter. So, to make the poodle Class work properly, we would need the following:

    class Poodle extends Dog {
            public function bark( ) {
                    print "Yip!\n";
            }

            public function _ _construct($DogName) {
                    parent::_ _construct($DogName);
                    print "Creating a poodle\n";
            }
    }

The output should be this:

    Creating Poppy
    Creating a poodle
    My name is Poppy. If you find me, please call 555-1234

Note that "Creating Poppy" is output before "Creating a poodle", which might seem backward, but it makes sense given that we call the Dog constructor before we do any Poodle code. It is always best to call parent::_ _construct( ) first from the constructor of a child class, in order to make sure all the parent's properties are set up correctly before you try and set up the new stuff.

8.10.2. Destructors

Constructors are very useful, as I am sure you will agree, but there is more: PHP also allows you to define class destructors a method to be called when an object is deleted. PHP calls destructors as soon as objects are no longer available, and the destructor method, _ _destruct( ), takes no parameters. For example:

    public function _ _destruct( ) {
            print "{$this->Name} is no more...\n";
    }

If you add that method into the Poodle class, all Poodles created will have that method called before being destroyed. Add that into the same script as the constructor we just defined for poodles, and run it againhere's what it outputs:

    Creating Poppy
    Creating a poodle
    My name is Poppy. If you find me, please call 555-1234
    Poppy is no more...

Like constructors, destructors are only called onceyou need to use parent::_ _destruct( ). The key difference is that you should call parent::_ _destruct( ) after the local code for the destruction, so that you are not destroying properties before using it. For example:

    public function _ _destruct( ) {
            print "{$this->Name} is no more...\n";
            parent::_ _destruct( );
    }

8.10.3. Deleting Objects

So far, our objects have been automatically destroyed at the end of the script they were created in, thanks to PHP's automatic garbage collection. However, you will almost certainly want to arbitrarily delete objects at some point in time, and this is accomplished using unset( ) in the same way as you would delete an ordinary property.

It is important to note that calling unset( ) on an object will call its destructor before deleting the object, as you would expect.


Previous
Table of Contents
Next