views:

63

answers:

2

Hello I need to get only the methods declared in a class, and not the inherited methods. I need this for cakePHP. I am getting all the controllers, loading them and retrieving the methods from those controllers. But not only are the declared methods coming, but also the inherited ones.

Is there any method to get only declared methods.

A: 

From an architectural point of view, I think that reflection should be avoided if possible, but take a look at ReflectionClass->getMethods() if you think you know what you're doing.

<?php

class A {
    public function x() { }
    public function y() { }
}

class B extends A {
    public function a() { }
    public function b() { }
    public function x() { } // <-- defined here
}

$r = new ReflectionClass('B');
print_r($r->getMethods());

?>

You will get a list of methods defined by B and A, along with the class that last defined it. This is the output:

Array
(
    [0] => ReflectionMethod Object
        (
            [name] => a
            [class] => B
        )

    [1] => ReflectionMethod Object
        (
            [name] => b
            [class] => B
        )

    [2] => ReflectionMethod Object
        (
            [name] => x
            [class] => B
        )

    [3] => ReflectionMethod Object
        (
            [name] => y
            [class] => A
        )

)
Archimedix
@Archimedix: "From an architectural point of view, I think that reflection should be avoided if possible" why is that?
chelmertz
Hm, I guess it's personal preference. To me, reflection is similar to patching executables in-memory and *can* be unexpected (or expose such behavior) unless well-documented and can make your code more convoluted or introduce side-effects. However, it may prove useful for writing frameworks and meta-programming / extending a language's features.
Archimedix
+5  A: 

You can do this (although a little more than "simple") with ReflectionClass

function getDeclaredMethods($className) {
    $reflector = new ReflectionClass($className);
    $methodNames = array();
    $lowerClassName = strtolower($className);
    foreach ($reflector->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
        if (strtolower($method->class) == $lowerClassName) {
            $methodNames[] = $method->name;
        }
    }
    return $methodNames;
}
ircmaxell
@ircmaxell: why are you using `ReflectionMethod::IS_PUBLIC`?
chelmertz
To limit it to public only methods. If you want all methods, just omit that...
ircmaxell
@ircmaxell: It should be mentioned though, since it makes the answer incomplete to the question.
chelmertz
Thanks ircmaxell!!
macha