Jak psal na Intervalu nedávno Ronnie, jednou ze změn v Zend Frameworku v řadě 1.8 je autoloading. Ve zmíněném článku je popsáno o co jde a jak upravit svůj kód tak aby více méně fungoval i pod verzí 1.8. Pokusím se na toto téma podívat trochu z jiného pohledu.
Alespoň dva autolodery
První věc, kterou si je třeba uvědomit, je to, že v aplikaci se budete muset pravděpodobně zabývat minimálně dvěma typy autoloaderů, dříve byl ve frameworku v podstatě jen jeden autoloder na všechno.
První je klasický "globální" autoloader, který se stará o nahrávání tříd podle namespaces konvencí z include_path
. Jeho API se také od verze 1.7 podstatně změnilo o tom více ve výše zmíněném článku.
Druhým typem autoloaderů jsou tzv. resources loadery, které slouží zejména k nahrávání tříd s různými aplikačně specifickými zdroji jako jsou formuláře, front controller pluginy, helpery atd. Jeho představitelem je zejména Zend_Application_Module_Autoloader
, který zajišťuje nahrávání resources podle doporučených adresářových konvencí frameworku. Nic vám však nebrání použít jeho předka Zend_Loader_Autoloader_Resource
pro vlastní uspořádání adresářů či si napsat úplně vlastní resource loader implementující resource loader interface.
Propojení loaderů
Jde o to, že musíme našemu "hlavnímu" loaderu říci, že pro naše resource chceme používat náš resource loader. Tato věc součástí Zend_Loader_Autoloader_Resource
a vypadá takto
Zend_Loader_Autoloader::getInstance()->unshiftAutoloader($this, $namespace);
To znamená, že resource loader se přidá na začátek seznamu všech loaderů v našem hlavním globálním loaderu. Pokud tedy určitá třída v daném namespace nebude nahrána naším resource loaderem, tak se o její nahrání pokusí hlavní autoloader přes include_path.
Zend_Application a zpětná kompatibilita s non namespace modely
Takže už víme to hlavní o rozdílech v loaderech ve frameworku verze 1.8. Na první pohled je vidět, že framework nově velmi tlačí na používání namespaces a to i v resources (modely, formuláře). To nám může trochu nabourat náš původní kód, zejména modely. Spousta lidí nepoužívala namespaceované business třídy modelů. Většinou jste měli třídy jako User, Product, Ticket
nikoli MyApp_User,
MyApp_Product, MyApp_Ticket
. Většinou jste je také měli umístěné někde v adresáři models
, ten jste měli v include_path
a nahrávali je přes klasický globální autoloader. Toto můžete použít i dnes, jen musíte povolit toto chování v globálním autoloaderu takto:
$appAutoloader->setFallbackAutoloader(true);
Nebudu se více rozepisovat o podrobnostech novinky Zend_Application
, co se týká autoloaderů jde o to je nějak inicializovat podle nových pravidel Zend_Application
a použít výše zmíněné nastavení pro zpětnou kompatibilitu pojmenování modelů. Toho docílíme níže popsanou metodou třídy našeho aplikačního bootstrapu. Je tam ještě jedna věc, o které jsem se nezmínil, nastavení výpisu chyb globálního autoloderu při nezdařeném nahrání třídy pokud jsme v módu jiném než produkčním - metoda suppressNotFoundWarnings
. Obě věci - setfallbackAutoloader()
a suppressNotFoundWarnings()
je dobré si pohlídat, protože implicitní nastavení je takové, že se fallbackAutoloader nepoužije - původně pojmenované modely se nebudou nahrávat a notFoundWarnings se nevypisují.
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { /** * Bootstrap autoloader for application resources. * It also makes settings in an application autoloader. * @return Zend_Application_Module_Autoloader */ protected function _initAutoload() { /** application autoloader * @var Zend_Loader_Autoloader */ $appAutoloader = $this->getApplication()->getAutoloader(); //enable classic include path directory loader $appAutoloader->setFallbackAutoloader(true); //enable warnings for autoloading errors $appAutoloader->suppressNotFoundWarnings($this->getApplication()->getEnvironment() == "production"); //resource autoloader $autoloader = new Zend_Application_Module_Autoloader(array( 'namespace' => 'HomeWebApp', 'basePath' => dirname(__FILE__), )); return $autoloader; }
To nic nemění na tom, že časem by bylo vhodné názvy tříd modelů dát pod namespace a použít na ně resource loader, nejlépe Zend_Loader_Autoloader_Resource
a přidržet se konvencí frameworku pro pojmenování adresářů, ty jsou zde.
Komentáře (4)
vím že to sem nepatří, ale nevidím nikde kontakt na tebe:
RSS článků obsahuje komentáře, tak to pls oprav
a tohle smaž :-)
jj, vcera to jeste bylo ok, ale dnes rano jsem dostal z tveho RSS i komentare k clankum
Je to nejaka feature-a, kdyz jo tak pls oddel kometare k clankom a od clanku
Pro kazde by mnel by zvlast RSS kanal
Dekuji za rychli fix, nez se mi tve RSS zabordeluji komentarema
[2] Taktéž toto pozoruji.
[1][2][3] - Ano, přehodil jsem to na novou verzi (je v repositáři) už na Zend Frameworku 1.8.x, kterou jsem zhusta upravoval, takže tam jsou chyby, které jsem nevychytal, omlouvám se, to se holt stává.
To rss by mělo být opraveno.
Komentáře jsou uzavřeny.