2011-07-12 10 views
19

muszę ustalić, po wszystkie pliki zostały uwzględnione, które klasy rozszerzyć klasę nadrzędną, więc:Uzyskaj wszystkie zdefiniowane klasy klasy dominującej w php

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

i chciałbym, aby móc chwyć tablicę taką jak:

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

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

+0

Niezupełnie, wymaga to uruchomienia funkcji konstruktora, szukam zadeklarowanych klas, które niekoniecznie zostały jeszcze uruchomione. – Trey

+1

Możliwy duplikat [Uzyskaj wszystkie rozszerzone klasy w PHP] (http: // stack overflow.com/questions/16680040/get-all-extended-classes-in-php) – jeremy

Odpowiedz

18

Jeśli potrzebujesz tego, to naprawdę pachnie jak zły kod, klasa bazowa nie powinna o tym wiedzieć.

Jednakże, jeśli definicje zostały zawarte (czyli nie trzeba o nowe pliki z klasami ewentualnie mają), można uruchomić:

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

to w zasadzie to, co mam, z wyjątkiem tego, że używam 'is_a' zamiast' instanceof' ...i rozumiem, dlaczego tak myślisz, ale klasa podstawowa tak naprawdę nie musi nic wiedzieć, to jest bardziej jak funkcja menedżera wtyczek :) – Trey

+0

Ack, to może być ważna sprawa. Jeśli to w zasadzie to, co masz, czy to nie działa/czy jest jakiś problem, czy po prostu pytasz o potwierdzenie, że nie ma lepszej/szybszej metody? – Wrikken

+0

tylko upewniając się, że nie ma lepszej metody, dziękuję :) – Trey

4

Zastosowanie

$ allClasses = get_declared_classes();

, aby uzyskać listę wszystkich klas.

Następnie użyj PHP's Reflection feature, aby zbudować drzewo dziedziczenia.

+0

Wiem, że to już jest stare, ale dziękuję za skierowanie mnie na zajęcia z refleksji, brakuje im pełnej dokumentacji większości php.net, ale są one bardzo przydatne w kilku różnych miejscach +1 – Trey

16

Biorąc odpowiedź Wrikken i korygowania go za sugestię Scott Bonami i masz:

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

Inne propozycje is_a() i instanceof nie działają na tym, ponieważ oboje oczekiwać instancję obiektu, nie nazwa klasy.

2

Jestem pewien, że poniższe rozwiązanie lub coś takiego byłoby dobrym rozwiązaniem problemu. IMHO, można wykonać następujące czynności (co jest rodzajem wzorca obserwatora):

1- zdefiniować interfejs nazwać Fooable

interface Fooable{ 
    public function doSomething(); 
} 

2- Wszystko twój cel klasy muszą implementować ten interfejs:

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

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

3- Zrób rejestratora klasy nazywają to 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- Gdzieś w skrypcie startowym lub jakiś skrypt, który jest zawarty w skrypcie startowym:

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

5- w głównym kodzie:

class FooClient{ 

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

Jeśli spojrzysz na komentarze i zaakceptowana odpowiedź, problem polega na tym, że ja 1) nie chciałem wiedzieć o klasach dziecka z wyprzedzeniem (krok 4 wymaga ode mnie rejestracji każdej klasy dziecka) i 2.) Nie chciałem właściwie utworzyć instancje, po prostu je wypisz. – Trey

+1

Pozwól mi zadać ci pytanie w inny sposób, dlaczego miałbyś tego potrzebować? Chodzi mi o to, dlaczego musisz zdobyć wszystkie klasy, które odziedziczą klasę, nie znając ich przed czasem? –

+1

Oznaczyłeś swoje pytanie jako OOP, dlatego zamieszczam tę odpowiedź, ponieważ tak wygląda rozwiązanie OOP :) –