2011-07-12 26 views
19

我需要確定,畢竟文件已被包括在內,這班擴展父類,所以:獲取所有定義的父類的類在PHP

class foo{ 
} 
class boo extends foo{ 
} 
class bar extends foo{ 
} 

,我希望能夠抓住一個數組,如:

array('boo','bar'); 
+0

http://stackoverflow.com/questions/538863/getting-the-name-of-a-child-class-in-php –

+0

不完全是這樣,需要構造函數才能運行,我正在尋找聲明的類,這些類不一定已經運行了 – Trey

+1

[在PHP中獲取所有擴展類](http:// stack overflow.com/questions/16680040/get-all-extended-classes-in-php) – jeremy

回答

18

如果你需要,它真的聞起來像不好的代碼,基類應該不需要知道這一點。

然而,如果你的定義已被列入(即你不需要包括與你可能有新的類文件),你可以運行:

$children = array(); 
foreach(get_declared_classes() as $class){ 
    if($class instanceof foo) $children[] = $class; 
} 
+2

這基本上是我所擁有的,除了我使用'is_a'而不是'instanceof' ...我明白你爲什麼會這麼想,但基類實際上並不需要知道任何東西,這更像是一個插件管理器函數:) – Trey

+0

Ack,這可能是一個有效的情況。如果這基本上就是你所擁有的,它是行不通的/是否有問題,或者你只是要求確認沒有更好/更快的方法? – Wrikken

+0

只是確保沒有更好的方法,謝謝:) – Trey

4

使用

$ allClasses = get_declared_classes ();

得到所有類的列表。

然後,使用PHP's Reflection feature來構建繼承樹。

+0

我知道現在這已經很老了,不過謝謝你指點我的反思類,他們缺乏大部分php.net的完整文檔,但它們在一些不同的地方非常有用+1 – Trey

16

以Wrikken答案,並用斯科特博納米的建議糾正它,你會得到:

$children = array(); 
foreach(get_declared_classes() as $class){ 
    if(is_subclass_of($class, 'foo')) 
    $children[] = $class; 
} 

is_a()instanceof其他建議不要對這個工作,因爲他們都希望對象的實例,而不是一個類名。

2

我非常肯定,下面的解決方案或類似的東西會非常適合您的問題。恕我直言,你可以做以下(這是一種觀察者模式):

1-定義的接口調用它Fooable

interface Fooable{ 
    public function doSomething(); 
} 

2 - 你的所有目標類必須實現該接口:

class Fooer implements Fooable{ 
    public function doSomething(){ 
     return "doing something"; 
    } 
} 

class SpecialFooer implements Fooable{ 
    public function doSomething(){ 
     return "doing something special"; 
    } 
} 

3-做一個註冊商類稱它爲FooRegisterar

class FooRegisterar{ 
    public static $listOfFooers =array(); 

    public static function register($name, Fooable $fooer){ 
     self::$listOfFooers[$name]=$fooer; 
    } 
    public static function getRegisterdFooers(){ 
     return self::$listOfFooers; 
    } 
} 

4-某處在你的啓動腳本或一些腳本,包括在啓動腳本:

FooRegisterar::register("Fooer",new Fooer()); 
FooRegisterar::register("Special Fooer",new SpecialFooer()); 

5-主代碼:

class FooClient{ 

    public function fooSomething(){ 
     $fooers = FooRegisterar::getRegisterdFooers(); 
     foreach($fooers as $fooer){ 
       $fooer->doSomthing(); 
     } 
    } 
} 
+0

如果你看看評論以及被接受的答案,問題是我不希望提前知道孩子課程(你的第4步要求我註冊每個孩子課程)和2.)我不想實際上實例化類,只是有一個列表。 – Trey

+1

讓我以另一種方式問你這個問題,爲什麼你需要這個?我的意思是,爲什麼你需要讓所有的班級在不知道他們提前知道的情況下繼承班級? –

+1

您將問題標記爲OOP,這就是爲什麼我發佈這個答案,因爲這是一個OOP解決方案的樣子:) –