tags:

views:

119

answers:

2

Given the following case:

<?php

class ParentClass {

    public $attrA;
    public $attrB;
    public $attrC;

    public function methodA() {}
    public function methodB() {}
    public function methodC() {}

}

class ChildClass extends ParentClass {

    public $attrB;

    public function methodA() {}
}

How can I get a list of methods (and preferably class vars) that are overridden in ChildClass?

Thanks, Joe

EDIT: Fixed bad extends. Any methods, not just public ones.

+2  A: 

You can use ReflectionClass to achieve this:

$ref = new ReflectionClass('ChildClass');

print_r($ref->getMethods());
print_r($ref->getProperties());

This will output:

Array
(
    [0] => ReflectionMethod Object
        (
            [name] => methodA
            [class] => ChildClass
        )

)

Array
(
    [0] => ReflectionProperty Object
        (
            [name] => attrB
            [class] => ChildClass
        )

)

See the manual for more useful information on reflection: http://uk3.php.net/manual/en/class.reflectionclass.php

Janci
@Janci: +1 for reflection class and yes it is very useful :)
Sarfraz
I don't think this would work if ChildClass was actually declared as extending ParentClass
Tom Haigh
This would also return any regular added classes and properties that do not overwrite a parent method or property
Gordon
@Tom: You are right, I overlooked that in the initial example, the ChildClass did not extend ParentClass, and just copied it as it was. Shall the ChildClass actually extend ParentClass, my solution will return all methods including those in parent class. Sorry about that. The correct solution involves iterating through returned methods and comparing $method->getDeclaringClass()->getName() with the class name you are interested in.
Janci
+5  A: 

Reflection is correct, but you would have to do it like this:

$child  = new ReflectionClass('ChildClass');

// find all public and protected methods in ParentClass
$parentMethods = $child->getParentClass()->getMethods(
    ReflectionMethod::IS_PUBLIC ^ ReflectionMethod::IS_PROTECTED
);

// find all parentmethods that were redeclared in ChildClass
foreach($parentMethods as $parentMethod) {
    $declaringClass = $child->getMethod($parentMethod->getName())
                            ->getDeclaringClass()
                            ->getName();

    if($declaringClass === $child->getName()) {
        echo $parentMethod->getName(); // print the method name
    }
}

Same for Properties, just you would use getProperties() instead.

Gordon
This is the way. Just use `getMethods()` then foreach through them calling `getDeclaringClass()->getName()`. If name != class name, then it's been overriden. The same can be done with `getProperties()`
webbiedave
lol. I didn't realize it was a work in progress or I wouldn't have added my comment.
webbiedave
@webbiedave I felt it was still too abstract to grasp. It's quite easy when you know how to do it but for someone new to the API it might be difficult. Plus, it was a nice exercise :)
Gordon