Autor | Zpráva | ||
---|---|---|---|
sitg Profil * |
#1 · Zasláno: 27. 8. 2010, 00:55:48
Ahoj,
mám problém při vytváření instance singletonu uvnitř jiného singletonu. Mám následující strukturu kódu: třída Singleton obsahuje metodu: public static function &getInstance() { if (($className = \get_called_class()) == __CLASS__) throw new \CreateInstanceException('Can not create instance of myself'); if (! isset(self::$instances[$className])) self::$instances[$className] = new $className; return self::$instances[$className]; } třída Storage rozšiřuje třídu Singleton a obsahuje metodu: public function setDriver($driver) { self::$driver = $driver; return self::getInstance(); } třída Security rozšiřuje třidu Singleton a v konstruktoru obsahuje volání: $storage = Storage::setDriver('TextFile'); Tady ale nastává problém. Protože "Storage::setDriver('TextFile')" nevrátí instanci třídy Storage, ale instanci třídy Security a tak dojde k zacyklení. Řešením je upravit funkci setDriver aby vracela "Storage::getInstance()" namísto "self::getInstance()". Dokázal by mi prosím někdo vysvětlit proč se to takhle chová? |
||
Majkl578 Profil |
#2 · Zasláno: 27. 8. 2010, 06:02:54
Je to tím, že metoda setDriver je volána staticky, ale není tak definována (pomocí
static ).
To způsobí, že funkce get_called_class vrací název třídy Security místo Storage a vznikne rekurze.
|
||
sitg Profil * |
#3 · Zasláno: 27. 8. 2010, 12:48:36
Nějak mi to přijde hodně nelogický. Teď jsem to studoval na php.net a podle toho by nemělo fungovat ani řešení problému se "Storage::getInstance()". Když to vezmu teoreticky: jako první zavolám Storage::setDriver v konstruktoru třídy Security, setDriver provede "self::$driver = $driver", což je funční a už nasvědčuje tomu že self je opravdu chápáno jako jméno Storage. Potom zavolání self::getInstance() volá statickou třídu getInstance(), kde by problém opět vzniknout neměl, protože getInstance() je statická. Problém tudíš musí vyvolávat až nelogické chování funkce get_called_class, která dělá "get_called_class — the "Late Static Binding" class name". Neexistuje nějaký postup jak vyseparovat poslední volanou třídu?
|
||
sitg Profil * |
#4 · Zasláno: 27. 8. 2010, 13:23:29
Tak jsem prošel manuály a asi bude nejlogičtější nechat vše jak je (pořebuju aby setDriver nebylo jen static) a budu volat "Storage::getInstance()". Bude tohle vždy funkční nebo mohu čekat v některých případech ještě nějaké překvapení?
|
||
Časová prodleva: 14 let
|
0