views:

98

answers:

3

I'm building a unit testing framework for PHP and I was curious if there is a way to get a list of an objects methods which excludes the parent class's methods. So given this:

class Foo
{

    public function doSomethingFooey()
    {
        echo 'HELLO THERE!';
    }
}

class Bar extends Foo
{
    public function goToTheBar()
    {
        // DRINK!
    }
}

I want a function which will, given the parameter new Bar() return:

array( 'goToTheBar' );

WITHOUT needing to instantiate an instance of Foo. (This means get_class_methods will not work)/

+2  A: 
$class_methods = get_class_methods('Bar');

From the PHP Documenation

This will not instantiate the class, and will allow you to get an array of all of the classes methods.

I'm not completely certain that this won't return parent class methods, but get_class_methods will work for uninstantiated classes. If it does, you can use Alix's answer to remove the parent's method from the array. Or Lukman's to use the reverse engineering aspect of PHP internal code base to get the methods.


BTW, if you type in new Bar(), it is going to create a new instance of Foo, as Bar extends Foo. The only way you can not instantiate Foo is by referring to it statically. Therefore, your request:

I want a function which will, given the parameter new Bar() return:

Has no possible solution. If you give new Bar() as an argument, it will instantiate the class.

Chacha102
Aww Man .. Now I feel bad for calling a Senior Software Developer out for not reading the manual.... I'll get over it...
Chacha102
First, I'd just like to point out that this does not actually answer the question, and it is smarmy.
Christopher W. Allen-Poole
Next, I'd like to suggest that it might behoove you to consider the fact there may be good reason I do not wish to instantiate Foo as a separate instance. An example might be the fact that Foo is a Singleton, which means that you cannot instantiate both Foo and Bar.
Christopher W. Allen-Poole
Finally, why the snide remark about reading the manual when your statement, "I'm not completely certain that this won't return parent class methods" is a clear statement that you have made the same error? Those who dwell in glass houses ought not throw stones...
Christopher W. Allen-Poole
I'm not asking you to instantiate bar. If you had take the time in which to read my answer, you would have realized that it does not, in anyway, ask you to instantiate a class.
Chacha102
And the mention about "I'm not completely certain..." is a clear statement only that I have not had the time to try it out myself. It doesn't mention it in the manual, so therefore I have not made the same error as you.
Chacha102
And finally, I have removed any sarcastic remarks that you may have been offended by. But, both my and Alix's answer do state that you have made an error thinking that `get_class_methods` cannot handle this task.
Chacha102
+8  A: 

Use ReflectionClass, for example:

$f = new ReflectionClass('Bar');
$methods = array();
foreach ($f->getMethods() as $m) {
    if ($m->class == 'Bar') {
        $methods[] = $m->name;
    }
}
print_r($methods);
Lukman
A: 

You can use get_class_methods() without instantiating the class:

$class_name - The class name or an object instance.

So the following would work:

$bar_methods = array_diff(get_class_methods('Bar'), get_class_methods('Foo'));

Assuming there aren't repeated methods in the parent class. Still, Lukman's answer does a better job. =)

Alix Axel