Omu, fii modern.
Ce vrei tu sa faci se numeste "dependency injection".
Mai specific - si in stadiul initial - ai vrut sa faci "contructor injection", dar te-ai lovit de faptul ca un copil trebuie sa ofere si dependintele parintelui, nu numai ale lui.
Acum faci de fapt "setter injection", prin __set().
Dar jista cateva probleme; unele mai mici, altele mai mari:
- __set este chemat numai daca proprietatea nu este accesibila; vei avea wtf-uri cand vei declara un "protected $member" si vei face "$class->member";
- sunt anti-setteri, fiindca poti schimba starea obiectului mai tarziu (deci obiectul debine "mutable"), spre deosebire de ctor injection, unde poti ascunde foarte bine proprietatile, ele fiind setate numai prima data (immutable);
- nu-i o idee buna sa impui arhitectura modelelor; nu numai ca tu impui o arhitectura anume (prin nevoia de a sub-clasa Model), dar oferi tot felul de colaboratori mai mult sau mai putin necesari (nu orice model lucreaza cu DB, traduce sau foloseste URI-uri); modelele trebuie lasate la libera alegere: daca vrei un simplu obiect, sa poti face asta, fara a extinde Model, si fara a necesita o conexiune la DB; imagineaza-ti ca trebuie sa testezi asa ceva. Cam dificil.
- daca pasezi un array, nu te poti folosi de "type hinting" sa impui un anumit tip (nu poti impune "SomeType" ca in "myMethod(SomeType $type)");
- amesteci autoloading-ul cu autowiring-ul (crearea de dependinte si injectarea lor)
- foloseste un DI container ca lumea (uite unul simplu:
https://github.com/silexphp/Pimple)
- foloseste autoloading de sec 21:
http://www.php-fig.org/psr/psr-4/examples/- n-ar strica sa folosesti Composer: nu numai ca-ti da un autoloader moca, dar deschide usa catre mii de alte tool-uri (gen un container DI)
Cu ocazia asta am incercat Pimple - nifty little tool:
http://pastie.org/10547579