A következő a cikksorozatokban - a Rubysztán blog történetében először - PHP-s témára kerül a sor, méghozzá a mostanság két legdivatosabb library, a Zend keretrendszer és a Doctrine összehangolására. Railsszel fejlesztők figyelem: jöhet egy kis Zend vs. Rails összehasonlítás:)
Az alábbi példakódok az elmúlt időszakban tett erőfeszítéseim eredményei, amelyben általános, több célra felhasználható Zend keretrendszerre épülő alkalmazás-váz létrehozását tűztem ki célul.
A példakódok követhetőek vagy teljes alkalmazás-váz letölthető a projekt Github oldaláról.
A sorozat első részeként egy, a Zend keretrendszerre épülő MVC alkalmazásváz létrehozása, a bootstrappelés és a hozzá kapcsolódó fogalmak kerülnek bemutatásra. A folytatás a Doctrine 1.2-es verziójának integrációjáról szól.
A Zend 1.8-as verziói előtt az alkalmazás indítása finoman szólva is eléggé hektikus területnek számított. Mivel a Zend keretrendszer moduláris felépítésűnek született, azzal az ötlettel, hogy a fejlesztőknek a legnagyobb szabadságot biztosítsa, a keretrendszer bootstrappelésére sem adott igazán egységes megoldást. Ez csak egy eredményhez: a tökéletes káoszhoz vezethetett. Félmegoldások és ötletek születtek, kinek ez, kinek az a megoldás működött - sajnos fejlesztőként a mindennapok során még nekem is ezekkel a katasztrófális megoldásokkal kell megbírkóznom.
Az 1.8-as verzió megjelenése azonban magával hozta a Zend_Application osztályt, és vele együtt a korábbi gondok megoldását, hiszen ez lehetővé teszi, hogy egységes és objektumorientált módon, egy osztályon keresztül végezhessük az alkalmazás bootstrappelését és konfigurációját. A megoldás fokozatosan finomodott, és véleményem szerint az egyik leghasznosabb fejlődést hozta hosszú idő óta a Zend keretrendszerbe.
Az alkalmazás indítása annyira legegyszerűsödött, hogy mindössze egy Zend_Application példányt kell létrehoznunk, amely két paramétert vár: a környezetét, és egy konfigurációs fájlt.
A példányosítást megtehetjük az alkalmazás belépő pontján, ez az én esetemben a public/index.php fájl - minden kérést ide fut be:
A public könyvtárba csak azoknak a fájloknak szabad kerülniük, amelyeket a webszervernek statikusan kell kiszolgánia, minden alkalmazásbeli logika ettől elválasztva, az application könyvtárba kerül.
# public/index.php
$application = new Zend_Application(
APP_ENV,
APPLICATION_ROOT . '/config/application.ini'
);
$application->bootstrap()->run();
A fenti kódsor használatához természetesen előbb szükségünk van:
A megfelelő osztályok eléréséhez, és néhány fontosabb útvonal definiálásához:
Én ezeket egy külön fájlban (__config/include_paths.php__) helyeztem el, amit szükséges esetben beincludolva fel tudok használni.
Itt adom hozzá az includepath-okhoz a Zend keretrendszer library/ könyvtárának elérését is, különben a public/index.php fájlban hiába hivatkoznék a Zend_Application osztályra._
A környezet megállapítása:
Ezt egyszerűen az APP_ENV környezeti változóból veszem, amely így bárhol beállíthatóvá válik:
Apache direktívával:
SetEnv APP_ENV development
Parancssorból:
export APP_ENV=development
Futás alatt PHP-ben:
setenv(‘APP_ENV’, ‘development’); getenv(‘APP_ENV’);
Így adott esetben könnyedén megváltoztathatom az alkalmazás futtatási környezetét ami lehetővé teszi, hogy eltérő beállításokat alkalmazzunk bizonyos helyezetekben: egy fejlesztői és egy éles rendszer szinte biztosan teljesen más beállításokat követel meg.
Az alkalmazandó beállításokat az Zend_Application a példányosításakor átadott konfigurációs állományból olvassa ki. Környezetet ebben - a PHP ini formátumú sémáiban megszokott módon - a jelek között hozhatunk létre (pl. [production] ).
Szerencsére a Zend keretrendszer konfigurációjó lehetővé tesz olyan alapvető dolgokat, mint a beállítások egymásból származtatása, felülbírálása. Én személy szerint azt a konvenciót követem, hogy minden alapbeállítást egy [default] címkével látok el, amelyet a további környezetek kiterjeszthetnek, így a szükséges beállítások egyszerűen felüldefiniálhatóak. Leszármaztatást a : jellel adhatjuk meg. Az alábbi példában az production(éles) környezet mindenben a default beállítasait használja, kivéve, hogy a regisztrációkról szóló értesítéseket egy másik címre irányítom át.
[default]
email.registration.email_to = csiszar.ati@gmail.com
[production : default]
email.registration.email_to = administrator@example.com
A konfiguráció beolvasása után az alkalmazás felállítása a bootstrappeléssel folytatódik, amelyet a következő kódsor hív meg:
$application->bootstrap();
A Zend_Application a bootstrap során a konfigurációban megadott Bootstrap osztályhoz fordul, amely egyszerűen lefordítva futtat minden benne megadott init prefixszel kezdődő metódust.
Például az initView metódus a nézetekhez tartozó alapvető feladatokat definiálhatja, és elvégzi bizonyos paraméterek beállítását:
# application/Bootstrap.php
public function _initView()
{
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->initView();
$viewRenderer->view->doctype('XHTML1_TRANSITIONAL');
}
A bootstrappelést ugyanakkor egyszerűbbé tehetjük, ha a fentihez hasonló metódusokat külön osztályokban, a Zend terminilógiájában úgynevezett erőforrás plugineken keresztül valósítjuk meg. Az erőforrások használatával a bootstrappelés modulárisabbá tehető: a gyakran használt erőforrások könnyedén átvihetőek lesznek egyik alkalmazásból a másikba.
Erőforrás létrehozásához a Zend_Application_Resource_ResourceAbstract absztrakt osztályt kell megvalósítanunk.
A fenti példa valahogy így nézne ki erőforráskét megvalósítva:
class zf_Application_Resource_XhtmlView extends Zend_Application_Resource_ResourceAbstract
{
public function init()
{
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->initView();
$viewRenderer->view->doctype('XHTML1_TRANSITIONAL');
}
}
Használatához az alkalmazás konfigurációjában PluginPath útvonalként kell regisztrálnunk az elérését:
# application.ini
pluginPaths.custom_resources = LIBRARY_PATH "/zf/Application/Resource"
Az erőforrás osztály automatikus meghívását a bootstrap során egy hozzá kapcsolódó beállítás megadásával érhetjük el, amit könnyedén elérhetünk, hiszen a resources tömbön keresztül lehetőségünk van rá hivatkozni:
resources.xhtmlview.[]
Ebből következik,hogy mivel a bootstrap során az alap építőelemeit (a MVC mintához elengedhetetlen FrontController, View, Router stb. elemeket) a Zend keretrendszer maga is ilyen Resource-okon keresztül hívja meg, a konfigurációs állományból ezek rendkívül könnyen konfigurálhatóak lesznek. Az alábbi példában például egyszerűen meg tudom adni az MVC mintában elengedhetetlen controller osztályok elérését:
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
Ha mindezzel megvagyunk következhet az MVC M része, azaz a modellek kezelése, amelyre én a Doctrine ORM-t használtam fel.
A Zend_Framework - Doctrine integrációjáról a folytatásban olvashatsz.