PHP: How to call function of a child class from parent class

98,736

Solution 1

That's what abstract classes are for. An abstract class basically says: Whoever is inheriting from me, must have this function (or these functions).

abstract class whale
{

  function __construct()
  {
    // some code here
  }

  function myfunc()
  {
    $this->test();
  }

  abstract function test();
}


class fish extends whale
{
  function __construct()
  {
    parent::__construct();
  }

  function test()
  {
    echo "So you managed to call me !!";
  }

}


$fish = new fish();
$fish->test();
$fish->myfunc();

Solution 2

Okay, this answer is VERY late, but why didn't anybody think of this?

Class A{
    function call_child_method(){
        if(method_exists($this, 'child_method')){
            $this->child_method();
        }
    }
}

And the method is defined in the extending class:

Class B extends A{
    function child_method(){
        echo 'I am the child method!';
    }
}

So with the following code:

$test = new B();
$test->call_child_method();

The output will be:

I am a child method!

I use this to call hook methods which can be defined by a child class but don't have to be.

Solution 3

Technically, you cannot call a fish instance (child) from a whale instance (parent), but since you are dealing with inheritance, myFunc() will be available in your fish instance anyway, so you can call $yourFishInstance->myFunc() directly.

If you are refering to the template method pattern, then just write $this->test() as the method body. Calling myFunc() from a fish instance will delegate the call to test() in the fish instance. But again, no calling from a whale instance to a fish instance.

On a sidenote, a whale is a mammal and not a fish ;)

Solution 4

Since PHP 5.3 you can use the static keyword to call a method from the called class. i.e.:

<?php
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); // Here comes Late Static Bindings
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test();
?>

The above example will output: B

source: PHP.net / Late Static Bindings

Solution 5

Ok, well there are so many things wrong with this question I don't really know where to start.

Firstly, fish aren't whales and whales aren't fish. Whales are mammals.

Secondly, if you want to call a function in a child class from a parent class that doesn't exist in your parent class then your abstraction is seriously flawed and you should rethink it from scratch.

Third, in PHP you could just do:

function myfunc() {
  $this->test();
}

In an instance of whale it will cause an error. In an instance of fish it should work.

Share:
98,736
Sarfraz
Author by

Sarfraz

I am currently available for hire Recent Work: Quran CLI | Whatsapp CLI | Floyer | Phexecute Pakistan's top user on StackOverflow by reputation holding gold badge in PHP, jQuery, JavaScript, HTML and CSS tags. About Me I am a self-taught programmer mainly involved in PHP, MySQL, CSS/HTML, JavaScript/jQuery for around 7+ years now. Contact [email protected] → My LinkedIn Profile

Updated on November 09, 2020

Comments

  • Sarfraz
    Sarfraz over 3 years

    How do i call a function of a child class from parent class? Consider this:

    class whale
    {
      function __construct()
      {
        // some code here
      }
    
      function myfunc()
      {
      // how do i call the "test" function of fish class here??
      }
    }
    
    class fish extends whale
    {
      function __construct()
      {
        parent::construct();
      }
    
      function test()
      {
        echo "So you managed to call me !!";
      }
    
    }
    
  • Sarfraz
    Sarfraz over 14 years
    anyways, i could not understand your answer, can u suggest an alternative to it?
  • Gordon
    Gordon over 14 years
    I doubt it can be done with Reflection. Whale would have to have Fish hardcoded somewhere.
  • Sarfraz
    Sarfraz over 14 years
    this is just an example dude, i am not going to implement those names anywhere :)
  • Gordon
    Gordon over 14 years
    While correct, I think he wants to do $whale = new Whale; $fish = new Fish; and then $whale->myfunc(); is supposed to call $fish->test(); without knowing $fish exists.
  • philfreo
    philfreo over 14 years
    +1, abstract methods are generally the answer to your question of having parent classes refer to methods in child classes. If Gordon is correct and you're really trying to do something different/specific like that, you should clarify. Otherwise, this should be accepted.
  • Ben Fransen
    Ben Fransen over 10 years
    If all child classes have the same methods you can also consider implementing an interface to the child classes. Thereby you're able to exclude the method_exists() in the parent class.
  • Dariux
    Dariux over 10 years
    I searched also this, but your answer does not sovel what I want:whale = new whale(); $whale->test(); :( So one thing which I am thinking about - when called whale controller, then just redirect to fish controller and call. But somehow it feels that redirects are lagging.
  • mamdouh alramadan
    mamdouh alramadan about 10 years
    +1 for- Firstly, fish aren't whales and whales aren't fish. Whales are mammals.
  • azerafati
    azerafati almost 9 years
    great, I can't thank you enough. I was stuck with my static classes where I don't have an instance of them to call, this was the only way I solved it.
  • tanovellino
    tanovellino almost 8 years
    You don't need to pass the $child reference. using if(method_exists($this,$FunctionToRun)) should be enough. Keep in mind that wordcontroller inherits all the functions in controller, and so wordControlObj->runAction() will check for existing functions in wordcontroller and controller classes. If wordController overrides any method in controller, then wordcontroller version will be called instead. If you happen to have a debugger, an easy way of tracking the run flow would be override in wordcontroller the method just by using: function RunAction() { parent::RunAction() }
  • Thielicious
    Thielicious almost 8 years
    This is unlogic. If that whale got no child class, it isn't extended - hence no method to call from it.
  • merkdev
    merkdev over 7 years
    @TomSawyer can you please provide any proof or any benchmark results?
  • davewoodhall
    davewoodhall almost 6 years
    @Marius "A fish is a fish, a whale is a mammal." --- What the hell does this have to do with anything? It's a class name. Does the code work? That's the real question here. Because your answer could have just been a comment (it doesn't try solve the issue in any way), and because you are very condescending, I will downvote this answer.
  • Sachin Sarola
    Sachin Sarola over 5 years
    @Christian Engel may be you are wrong the questioner try to say something like creating object of class A and using this object they want to try call method of class B. May Be my understanding wrong.
  • Sachin Sarola
    Sachin Sarola over 5 years
    @FlorianH I have question in this we are not able to create object of whale class because abstract class object creating is not possible. But in my case some other function inside parent class how can I manage easily please suggest if any way.
  • Rain
    Rain almost 5 years
    You in fact are calling a method of class B to call another method of class B :|
  • Christian Engel
    Christian Engel almost 3 years
    Yes, absolutely @rain! The reason why this pattern is interesting is, that you can ignore if a child class implements a given method. The "guard" or hook method will always be there, tests if the child class implements the "real" method and calls it.
  • Rain
    Rain almost 3 years
    @ChristianEngel Besides that this is a violation of single responsibility, there’s no guarantee that someone won’t just call $test->child_method(). I think an interface contract will be best if the only thing that matters is if a certain class has a certain method. And then check if that class implemented the intended interface.