您好,我只需要獲取在類中聲明的方法,而不是繼承的方法。我需要這個CakePHP。我得到所有的控制器,加載它們並從這些控制器中檢索方法。但是,不僅宣稱的方法即將到來,而且還有繼承的方法。獲取PHP中只有聲明的類的方法
是否有任何方法只獲取聲明的方法。
您好,我只需要獲取在類中聲明的方法,而不是繼承的方法。我需要這個CakePHP。我得到所有的控制器,加載它們並從這些控制器中檢索方法。但是,不僅宣稱的方法即將到來,而且還有繼承的方法。獲取PHP中只有聲明的類的方法
是否有任何方法只獲取聲明的方法。
你可以做到這一點(雖然比 「簡單」 多一點)與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
)
)
「從架構的角度來看,我認爲如果可能的話應該避免反思」爲什麼? – chelmertz 2010-09-14 20:49:08
嗯,我想這是個人喜好。對我而言,反射與修補內存中的可執行文件類似,*可能會意外(或暴露此類行爲),除非有詳細記錄,並且可能會使代碼更復雜或引入副作用。但是,它可能對編寫框架和元編程/擴展語言功能非常有用。 – Archimedix 2010-09-14 21:14:55
遇到了一個評論:「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;
}
我知道沒有方法,除了複雜的反射的東西。你需要做什麼? – 2010-09-14 20:36:12
你能告訴我你爲什麼這麼做嗎?是爲了文檔還是在應用程序中使用? – 2010-09-14 20:37:12
我需要將所有控制器中的公共方法添加到我的權限表中。我正在使用cakePHP,他們的ACL組件不能與我擁有的現有模型一起工作。 – macha 2010-09-14 20:39:02