35

In the sample code below, the method test() in parent class Foo is overridden by the method test() in child class Bar. Is it possible to call Foo::test() from Bar::test()?

class Foo 
{
  $text = "world\n";

  protected function test() {
    echo $this->text;
  }
}// class Foo

class Bar extends Foo 
{
  public function test() {
    echo "Hello, ";

    // Cannot use 'parent::test()' because, in this case,
    // Foo::test() requires object data from $this
    parent::test();
  }
}// class Bar extends Foo

$x = new Bar;
$x->test();
8
  • Please edit your question to include the code directly... Commented Nov 10, 2011 at 0:10
  • 1
    What do you mean by foo::test() REQUIRE_DISABLED object data from $this
    – nickb
    Commented Nov 10, 2011 at 0:11
  • @Oli Charlesworth - I tried many times but I cant figure how to do it correctly, thats why I use pastebin :)
    – kiler129
    Commented Nov 10, 2011 at 0:13
  • 1
    You cannot overload methods in PHP, you can only override. Check the notes sections at the top: php.net/manual/en/language.oop5.overloading.php Commented Nov 10, 2011 at 0:13
  • 3
    @kiler129: When you use parent::method() from an object context, the parent method still has access to $this.
    – MrTrick
    Commented Nov 10, 2011 at 0:29

5 Answers 5

48

Use parent:: before method name, e.g.

parent::test();

See parent

0
6
parent::test();

(see Example #3 at http://www.php.net/manual/en/language.oop5.paamayim-nekudotayim.php)

1
  • You're right - using parent:: from child class will refer to object and will call object method (not static method). Thank for help :)
    – kiler129
    Commented Nov 10, 2011 at 0:22
0

Just set visibility levels at $text property.

private $text = "world\n";
-1

Calling a parent method may be considered bad practice or code smell and may indicate programming logic that can be improved in a way, that the child doesn't have to call the parent. A good generic description is provided by Wikipedia.

An implementation without calling parent would look like:

abstract class Foo
{
    $text = "world\n";

    public function test() {
        $this->test_child();
        echo $this->text;
    }

    abstract protected function test_child();
}// class Foo

class Bar extends Foo
{
    protected function test_child() {
        echo "Hello, ";
    }
}// class Bar extends Foo

$x = new Bar;
$x->test();
5
  • Putting a call to a function that may or may not exist in an extended class is smellier than overloading the function and calling the parent. In your example we have to be assured that the child function exists - you would either need to stub the function in the child class or use an interface. It's generally much nicer if a parent class doesn't need to know about its extended children at all. I would say you're better off making the same function in your child class and calling parent::function() from there instead Commented Sep 18, 2019 at 6:36
  • What do you mean "Putting a call to a function that may or may not exist in an extended class"? In fact if it is an abstract method in the parent class, the child class MUST implement it, otherwise you will get something like FATAL ERROR Class Bar contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Foo::test_child) when trying to run it. There's no "may or may not". If it's declared like that, it WILL exist or code won't run. It cannot be missed, it's not a promise or guess, it's a declaration. Commented Sep 18, 2019 at 12:57
  • "I would say you're better off making the same function in your child class and calling parent::function() from there instead" The problem with that, is that you cannot enforce the children to call the parent method. If you have anything critical in that parent method, and the children forgets to call it, that will cause Runtime headache potentially hard to even detect. My solution however doesn't let the child decide if the parent method should be called or not, and if the child fails to implement the required method, it is a Compile time issue: announces itself automatically and easy to fix. Commented Sep 18, 2019 at 13:28
  • I suppose it also depends on the data flow - do you want the child function to be called before the parent logic, or after? That would influence who calls who. Commented Sep 19, 2019 at 1:32
  • I'd say not really. The call to the abstract method can be put as the first or last line of the parent method, or even in the middle, or inside conditions, loops etc. That would cover the said use-cases, and again even deliver more in terms of flexibility. Commented Sep 19, 2019 at 7:08
-2

Judging by your comments on the pastebin, I'd say you can't.

Maybe if you had something like this?

class foo {
    public function foo($instance = null) {
        if ($instance) {
            // Set state, etc.
        }
        else {
            // Regular object creation
        }
}
class foo2 extends foo {
    public function test() {
        echo "Hello, ";
        // New foo instance, using current (foo2) instance in constructor
        $x = new foo($this);
        // Call test() method from foo
        $x->test();
    }
}
5
  • Why not just pass the parameters needed from $this to foo()? (Instead of the whole thinh)
    – nickb
    Commented Nov 10, 2011 at 0:24
  • He can reference the parent version of test by prefixing with parent::test(), as mentioned in the other posts. You may want to consider for delete before getting down voted. Commented Nov 10, 2011 at 0:24
  • @jeanreis - in my code is nearly impossible to use tricks like this above, bcs object sometimes weight few megabytes (it`s an server app, not classic web-script ofc). Doing tricks like that will cause high memory usage.
    – kiler129
    Commented Nov 10, 2011 at 0:25
  • regarding the parent::test(), I was under the impression that the method could not be called statically, hence my answer. That was just a suggestion, withouth knowing specifics it's hard to tell if it's viable.
    – jeanreis
    Commented Nov 10, 2011 at 0:29
  • Well ... PHP as [semi]true-objective language is very young :)
    – kiler129
    Commented Nov 10, 2011 at 0:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.