Получить только объявленные методы класса в PHP - PullRequest
6 голосов
/ 15 сентября 2010

Здравствуйте, мне нужно получить только методы, объявленные в классе, а не унаследованные методы. Мне нужно это для cakePHP. Я получаю все контроллеры, загружаю их и извлекаю методы из этих контроллеров. Но приходят не только объявленные методы, но и унаследованные.

Есть ли способ получить только объявленные методы.

Ответы [ 3 ]

9 голосов
/ 15 сентября 2010

Вы можете сделать это (хотя и немного больше, чем просто) с помощью 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;
}
1 голос
/ 15 сентября 2010

С архитектурной точки зрения, я думаю, что отражения следует избегать, если это возможно, но посмотрите на ReflectionClass-> getMethods () , если вы думаете, что знаете, что делаете.

<?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());

?>

Вы получите список методов, определенных B и A, вместе с классом, который его определил последним. Это вывод:

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
        )

)
0 голосов
/ 09 октября 2014

Наткнулся на комментарий: «ReflectionClass :: getMethods () сортирует методы по классу (сначала в дереве наследования сначала наименьший), затем по порядку, который они определены в определении класса» здесь - http://php.net/manual/en/reflectionclass.getmethods.php#115197

Я проверил это, и это похоже на правду.Исходя из этого, мы можем добавить небольшую оптимизацию в решение ircmaxell, чтобы избежать итерации по другим унаследованным методам.Также добавлена ​​некоторая очистка, чтобы избежать конструктора \ деструктора:

public function getMethods($className) 
{   
    $methodNames = [];
    $reflectionClass = new ReflectionClass(className); 
    $publicMethods = $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC);
    $lowerClassName = strtolower($className);
    foreach ($publicMethods as $method) {
        if (strtolower($method->class) == $lowerClassName) {
            // You can skip this check if you need constructor\destructor  
            if (!($method->isConstructor() ||
                $method->isDestructor())) {
                $methodNames[] = $method->getName();
            }
        } else {
            // exit loop if class mismatch
            break;
        }
    }
    return $methodNames;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...