14

Is it possible to check whether or not a method has been overridden by a child class in PHP?

<!-- language: lang-php -->

class foo {
    protected $url;
    protected $name;
    protected $id;

    var $baz;

    function __construct($name, $id, $url) {
        $this->name = $name;
        $this->id = $id;
        $this->url = $url;
    }

    function createTable($data) {
        // do default actions
    }
}

Child class:

class bar extends foo {
    public $goo;

    public function createTable($data) {
        // different code here
    }
}

When iterating through an array of objects defined as members of this class, how can I check which of the objects has the new method as opposed to the old one? Does a function such as method_overridden(mixed $object, string $method name) exist?

foreach ($objects as $ob) {
    if (method_overridden($ob, "createTable")) {
        // stuff that should only happen if this method is overridden
    }
    $ob->createTable($dataset);
}

I am aware of the template method pattern, but let's say I want the control of the program to be separate from the class and the methods themselves. I would need a function such as method_overridden to accomplish this.

4
  • Overloaded, or overridden? I thought PHP didn't have method overloading Commented Jul 15, 2013 at 20:23
  • I did mean over-ridden, yes Commented Jul 15, 2013 at 20:24
  • 1
    You could try this: php.net/manual/en/reflectionclass.hasmethod.php Commented Jul 15, 2013 at 20:26
  • 2
    If your design is dependant on knowing how classes have overridden particular methods, then there's something seriously wrong with your design. The whole idea behind OO is that you can send a message to an object and it's up to the object to handle it in an appropriate way. The calling code shouldn't care what implementation is being called or how its message is being dealt with. Commented Nov 7, 2013 at 9:39

2 Answers 2

25

Check if the declaring class matches the class of the object:

$reflector = new \ReflectionMethod($ob, 'createTable');
$isProto = ($reflector->getDeclaringClass()->getName() !== get_class($ob));

PHP Manual links:

Sign up to request clarification or add additional context in comments.

3 Comments

This is certainly the way I want to go about it, but I have a question: for what reason are you using the namespace operator before ReflectionMethod? Is it to ensure that method is being called from the global namespace instead of accidentally calling a method of the same name defined in a more local scope?
It's probably not needed in your case. If the code above is under a namespace, you would need to either import the ReflectionMethod class, or access it with global namespace prefix (`\`). I'm just making sure this situation is handled :)
This can be done with class properties as well. Just use \ReflectionProperty() instead.
2

To get this information, you have to use ReflectionClass. You could try getMethod and check the class name of the method.

$class = new ReflectionClass($this);
$method = $class->getMethod("yourMethod");
if ($method->class == 'classname') {
    //.. do something
}

But keep in mind, that reflection isn't very fast, so be careful with usage.

1 Comment

In PHP 5.5.20 the $method['class'] gave me: Cannot use object of type ReflectionMethod as array. The $method->class worked just fine.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.