我想要的是所有公共方法的数组,只有公共方法的数组,来自继承树中的最低类。例如:
class MyClass { }
class MyExtendedClass extends MyClass { }
class SomeOtherClass extends MyClass { }
从MyClass的内部我想从MyExtendedClass和SomeOtherClass中获取所有PUBLIC方法。
我发现我可以使用Reflection Class来做到这一点,但是当我这样做时,我也从MyClass获取方法,我不想得到它们:
$class = new ReflectionClass('MyClass');
$methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);
有办法做到这一点吗?或者我在这种情况下唯一的解决方案就是过滤掉反射类的结果?
答案 0 :(得分:18)
不,我认为你不能一次过滤出父方法。但是通过类索引过滤结果非常简单。
$methods = [];
foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method)
if ($method['class'] == $reflection->getName())
$methods[] = $method['name'];
答案 1 :(得分:2)
我刚刚编写了一个方法,其中包含一些额外的功能,可以扩展Daniel的答案。
它允许您仅返回静态或对象方法。
它还允许您仅返回已在该类中定义的方法。
提供您自己的命名空间或只复制方法。
示例用法:
$methods = Reflection::getClassMethods(__CLASS__);
代码:
<?php
namespace [Your]\[Namespace];
class Reflection {
/**
* Return class methods by scope
*
* @param string $class
* @param bool $inherit
* @static bool|null $static returns static methods | object methods | both
* @param array $scope ['public', 'protected', 'private']
* @return array
*/
public static function getClassMethods($class, $inherit = false, $static = null, $scope = ['public', 'protected', 'private'])
{
$return = [
'public' => [],
'protected' => [],
'private' => []
];
$reflection = new \ReflectionClass($class);
foreach ($scope as $key) {
$pass = false;
switch ($key) {
case 'public': $pass = \ReflectionMethod::IS_PUBLIC;
break;
case 'protected': $pass = \ReflectionMethod::IS_PROTECTED;
break;
case 'private': $pass = \ReflectionMethod::IS_PRIVATE;
break;
}
if ($pass) {
$methods = $reflection->getMethods($pass);
foreach ($methods as $method) {
$isStatic = $method->isStatic();
if (!is_null($static) && $static && !$isStatic) {
continue;
} elseif (!is_null($static) && !$static && $isStatic) {
continue;
}
if (!$inherit && $method->class === $reflection->getName()) {
$return[$key][] = $method->name;
} elseif ($inherit) {
$return[$key][] = $method->name;
}
}
}
}
return $return;
}
}
答案 2 :(得分:1)
我有必要这样做并提出以下功能:
function getMethods($class, $visibility = "")
{
$reflect = new ReflectionClass($class);
$methods = [];
// Iterate the methods
foreach ($reflect->getMethods() as $value){
/*
* $value->getFileName() returns actual file name a method was set in.
* if it does not match the current filename it is a inherited method assuming a file contains only one class
*/
if ($value->getFileName() == $reflect->getFileName()) {
if ($value->isPublic() === true) {
$methods['public'][] = $value->name;
}
elseif ($value->isPrivate() === true) {
$methods['private'][] = $value->name;
}
elseif ($value->isProtected() === true) {
$methods['protected'][] = $value->name;
}
}
}
switch ($visibility) {
case "private":
case "public":
case "protected":
return $methods[$visibility];
break;
default:
return $methods;
break;
}
}
在Father.php和Child.php中使用以下测试代码
class Father{
public function parentTest() { }
}
class Child extends Father {
public function __construct() { }
private function test() { }
protected function test2() { }
}
返回以下内容:
array (size=3)
'public' =>
array (size=1)
0 => string '__construct' (length=11)
'private' =>
array (size=1)
0 => string 'test' (length=4)
'protected' =>
array (size=1)
0 => string 'test2' (length=5)