Здравствуйте, мне нужно получить только методы, объявленные в классе, а не унаследованные методы. Мне нужно это для cakePHP. Я получаю все контроллеры, загружая их и получая методы от этих контроллеров. Но не только объявленные методы приходят, но и унаследованные.
Есть ли способ получить только объявленные методы.
Вы можете сделать это (хотя и немного больше, чем «просто») с 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; }
С архитектурной точки зрения, я думаю, что, по возможности, следует избегать отражения, но взгляните на 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 ) )
Вышел через комментарий: «ReflectionClass :: getMethods () сортирует методы по классу (сначала в дереве наследования), а затем по порядку, который они определены в определении класса« здесь – http://php.net/manual/en /reflectionclass.getmethods.php#115197
Я проверил это, и это кажется правдой. Исходя из этого, мы можем добавить небольшую оптимизацию к решению ircmaxell, чтобы избежать повторения других унаследованных методов. Также добавлена некоторая очистка, чтобы избежать конструктора \ destructor:
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; }