Book HomePHP CookbookSearch this book

7.8. Accessing Overridden Methods

7.8.1. Problem

You want to access a method in the parent class that's been overridden in the child.

7.8.2. Solution

Prefix parent:: to the method name:

class shape {
    function draw( ) {
        // write to screen
    }
}

class circle extends shape {
   function draw($origin, $radius) {
      // validate data
      if ($radius > 0) {
          parent::draw( );
          return true;
      }

      return false;
   }
}

7.8.3. Discussion

When you override a parent method by defining one in the child, the parent method isn't called unless you explicitly reference it.

In the Solution, we override the draw( ) method in the child class, circle, because you want to accept circle specific parameters and validate the data. However, in this case, we still want to perform the generic shape::draw( ) action, which does the actual drawing, so we call parent::draw( ) inside your method if $radius is greater than 0.

Only code inside the class can use parent::. Calling parent::draw( ) from outside the class gets you a parse error. For example, if circle::draw( ) checked only the radius, but you also wanted to call shape::draw( ), this wouldn't work:[5]

[5]In fact, it fails with the error unexpected T_PAAMAYIM_NEKUDOTAYIM, which is Hebrew for "double-colon."

$circle = new circle;
if ($circle->draw($origin, $radius)) {
    $circle->parent::draw();
}

If you want to call the constructor belonging to an object's parent but don't know the parent's class name, use get_parent_class( ) to dynamically identify the parent, then combine that with parent:: to call the parent's constructor:

class circle extends shape {
    
    function circle( ) {
        $parent = get_parent_class($this);
        parent::$parent( );
    }
}

The function get_parent_class( ) takes a class name or an object and returns the name of the object's parent. In order to maintain generality, pass $this, which is the reference to the current object. In this case, the function returns shape. Then, use parent:: to ensure PHP explicitly calls the constructor in the parent class. Calling $parent( ) without parent:: runs the risk of calling a method in circle that overrides the parent definition.

The call to parent::$parent( ) may look a little odd. However, PHP just substitutes in the parent class name for the $parent variable. Then, because there are ( ) s after the variable, PHP knows it should make a method call.

It's possible to hardcode the call to parent::shape( ) directly into the circle constructor:

function circle( ) {
    parent::shape( );
}

However, this isn't as flexible as using get_parent_class( ). It is faster, so if you know your object hierarchy isn't going to change, that may be a trade-off you can benefit from.

Last, you can't chain the parent:: keyword to work back to a "grandparent" class, so, parent::parent::foo( ) doesn't work.

7.8.4. See Also

Recipe 7.3 for more on object constructors; documentation on class parents at http://www.php.net/keyword.parent and on get_parent_class( ) at http://www.php.net/get-parent-class.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.