szjani.hu

A régi blogom, ahova lehet írok majd még...

Elmélkedés a PHP keretrendszerekről

2012-12-07 4 perc olvasási idő

Nem tudom, ki hányszor hallott rosszat PHP programozókról, én személy szerint rengetegszer. A PHP programozók gányolnak. Ez az általános vélekedés. Valójában nagyjából minden script nyelv esetén ez a megítélés, kisebb-nagyobb eltérésekkel. Miért mondják ezt a Java, C++, C# programozók? Nos tény, hogy bár gányolni minden nyelven lehet, a PHP erre kifejezetten alkalmas is. Az viszont, hogy alkalmas, nem azt jelenti, hogy máshogy nem lehet. Tény, hogy a nyelvből sok dolog hiányzik, az API nem feltétlenül konzisztens, azért lehet benne jó kis weboldalakat írni. De valóban csak weboldalakat írunk PHP-ben? A legtöbbször ebből indulunk ki, és rengeteg félreértéshez vezet.

Az igazság

Milyen egyéb felhasználási területek vannak? Írhatunk webserviceket, cron jobokat, daemonokat. Mi a HTTP jelentősége a backend (PHP) felől nézve? Annyi csupán, hogy azon jön az adat. Jöhetne máshonnan is, sőt, összetett alkalmazásoknál jön is. Akik valamilyen MVC keretrendszerrel valaha is megismerkedtek, mi volt az első dolguk, amikor el akarták kezdeni a fejlesztést? Megnézni, hogy mi az ajánlott könyvtárstruktúra. Ahhoz alkalmazkodik mindenki, arra épít mindenki, aztán a saját - a keretrendszer számára idegen “típusú” - osztályainknak keresünk egy sötét sarkot.

Ha a HTTP csak egy interfész (márpedig az), akkor miért egy webes framework konvencióját követik alkalmazásaink? Miért erőltetjük rá az egész projektre az MVC-t? A keretrendszer azért van, hogy segítse a dolgunkat, nem azért, hogy megnehezítse. Ajánlom megtekintésre a következő felvételt.

DDD

Az utóbbi időben a DDD-vel kezdtem el foglalkozni, minél mélyebbre ásni a témában. A DDD-ben - mint ahogy a neve is mutatja (Domain-Driven Design) - a domainen van a hangsúly. Azon, amit az ügyfél elmond, azon, amely témában nekünk feladatunk lesz. Nem a framework érdekli az ügyfelet (legalábbis nem elsősorban), hanem működő megoldást szeretne. Elsődleges feladatunk, hogy modelleznünk kell az ő folyamatait. Az, hogy ezt majd egy weboldalon kattintgatva tudja használni, “lényegtelen”.

A DDD-ben a domain rétegben, ahol ez a modell található, nincs framework. Nem érdekel minket a web, nem érdekel az adatbázis, a levélküldés. Azok a munkafolyamatok érdekelnek, amiket eddig papíron, Excelben, elavult szoftverrel vezettek. Minden más az ez alatti, illetve feletti rétegek feladatai. Ebben az elrendezésben hol a helye az MVC frameworknek? Az interface rétegben, ami az alkalmazást kívülről elérhetővé teszi a web felől.

Nézzük meg, mit csinálunk egy átlagos projektben. Adatbázis lekérdezéseket, levélküldést, üzleti logikát teszünk a controllerbe, active rekordot használunk perzisztálásra, mindenhol keretrendszer specifikus elemeket használunk (pontosabban teszik ezeket mindazok, akik miatt az a megítélés a PHP programozókról, ami). Hogy lehet egy ilyen rendszert módosítani, egyes elemeit kicserélni? Szinte sehogy.

Javaban a Spring keretrendszerrel kezdtem el dolgozni. Nincs konvenció arra, hogy nézzen ki a projekt. Mitől lesz controller egy osztály? Véletlenül sem attól, hogy a “controllers” könyvtárban van. Minden a konfigurációtól függ. Ezt DIC-cel (erről írtam korábban), Springes nyelvhasználattal IoC-vel érhetjük el. Persze csak azért lehetséges mindez, mert nincsenek olyan varázslatok, mint a - főleg az első generációs - PHP-s frameworkökben.

Tranzakció kezelés, loggolás, cachelés. Hogy építjük be ezeket az alkalmazásokba? A legtöbbször sajnos direktben. Közvetlenül használjuk a PDO-t, EntityManagert (Doctrine), egyéb osztályokat, a frameworkbe épített logging osztállyal teleszórjuk az osztályainkat (ugye loggolunk?!), megintcsak a beépített cache megoldást égetjük a kódba.

Springben van tranzakció manager, ami elfedi előlünk a konkrét megvalósítást. Használhatunk alatta Hibernatet, vagy JPA-t, nem számít. Aztán van olyan, hogy slf4j, ami egy logging facade. Elrejti előlünk a valódi logging frameworköt (log4j, commons-logging, logback, stb.). Maga a Java is úgy fejlődik, hogy a hatékony, bizonyított libekből ötletet merítve próbálnak szabványt alkotni. Így van a Javaban JSR egy csomó mindenre. Mi van nekünk PHP-ben? Kvázi semmi. Pedig ezek nem eget rengető dolgok, “csak” szabványok.

Ezeken felbuzdulva az utóbbi hetekben megnéztem, mit lehetne tenni az ügy érdekében. Facade libeket készítettem loggoláshoz, tranzakció kezeléshez, illetve üzenet kezelésre. Ezek olyan fontos dolgok, amelyek nélkül egy jól karbantartható, DDD projekt elkészítése lehetetlen.

Megoldások(?)

lf4php

https://github.com/szjani/lf4php

Egy egy logging facade, önmagában nem csinál semmit. Illetve kiegészítettem egy Stdout loggerrel, ami CLI programoknál a kimenetre írásra elegendő, semmi másra. Valamint, egy külön libként, készítettem egy Monolog csatolót. Ezzel a Monologot tudjuk meghajtani az lf4php-ben definiált felületen keresztül. Vagyis a kódunkba - a konfiguráción kívül - sehol nem kell leírnunk, hogy “monolog”. Ha szükség van rá, akkor bármikor lecserélhetem másra, ha a Monolog nem tudná kielégíteni az igényeimet.

trf4php

https://github.com/szjani/trf4php

Ez egy nagyon egyszerű interfész a tranzakciók kezelésére. Pofátlanul egyszerű. Semmi mágia. És van egy Doctrine\EntityManager-t használó csatoló írva hozzá.

mf4php

https://github.com/szjani/mf4php

DDD-ben egy tranzakción belül két eltérő aggregatet nem kezelünk, helyette üzenetek küldésével, aszinkron módon váltjuk ki a kívánt hatást. A kulcsszó az aszinkron. PHP-ben erre sajnos - külső eszközök nélkül - nincs lehetőség. Javaban erre ott a JMS. Erre a problémára írtam ezt a facade-ot, amelyhez csak egy szinkron hívást közvetlenül támogató megoldás van. Ez pl. unit teszt futtatáskor elegendő lehet. Ehhez is készítettem egy valós implementációt, amely a Pheanstalk könyvtár segítségével Beanstalkkal kommunikál. Ily módon pedig már elérhető az aszinkron üzenetküldés.

Karácsonyi kívánság

Milyen jó lenne, ha a frameworkök ezeket (vagy ehhez hasonló) szabány API-kat implementálnának? Még az is lehet, hogy főállásban visszamennék PHP programozónak. Had emlékeztessek mindenkit: ne webalkalmazásokat csináljunk, hanem alkalmazásokat, amelyek elérhetők weben (is). Sokat nyerünk ezzel. És higgyétek el, vannak gány Java kódok is.

comments powered by Disqus