Neobsahuje názory Henryka Laholy

PHP framework, takříkajíc dva nula

FW trochu jinak, aneb Kdo si neudělal vlastní PHP framework, ten jako by nebyl...

Už to budou bajvočko tři roky, co jsem poprvé nasadil vlastní framework. Byla to, tuším, verze 2. "Nahoře" byl Prototype + Scriptaculous, celý frontend byl AJAXový a dole simulovalo PHP stavovou aplikaci.

Pak jsem dostal rozum, zahodil to a udělal verzi 3. Ta ani ven nešla. Pak jsem udělal verzi 4. Ta byla moc hezká, plná sexy vizuálních komponent a tak, ale taky to vedlo do pekel.

Následovalo několik různých verzí a "proof-of-concepts", během nichž jsem všechno několikrát zahodil a předělal, a nakonec jsem se odhodlal k radikálnímu kroku: Použiju nějaký existující framework!

Ne že by nebyly, je jich jak naseto. Ale není to vono. Buď řeší to, co řešit nepotřebuju, nebo neřeší to, co by se mi zrovna hodilo, některé jsou příliš oteklé a jiné podivné, zkrátka mi žádný nesedl natolik, abych si sedl a začal se ho učit (nesedl-sedl je záměrné!). Ani Nette, na které netrpělivě čekala úplně celá komunita a o němž spousta lidí básnila ještě předtím, než ho viděla. (Já věřím, že je Nette dobré, protože vím, že nad ním David přemýšlel a že ho používal už dost dlouho předtím, než ho uvolnil, na druhou stranu ale je o Davidovi známo, že "Kdyby toho totiž uměl tolik co kéca, tak neřeší jak se proslavit na lupě, ale uděla to sám") :)

Já neříkám, že jsou ty frameworky snad špatné, chraň PHPbu, jen mi zkrátka nesedly přesně k tomu, co jsem chtěl dělat a co jsem potřeboval.

Nakonec jsem se z každého trošku inspiroval a vytýčil jsem v jasné chvilce trasu, kudy se vše bude ubírat. PoC jsem si ověřil na Teidu. První verze (odlehčený a přepracovaný PoC) mého "new FW" běží na jdem.cz a chod.sk. Druhá verze byla zase přechodová (je použita jen na jednom webu, který jsem já nedělal a nevím, jestli je už veřejný, takže neodkážu) a teď roste verze třetí, která by mohla být konečně "milestone". A proč že o tom píšu, když vlastní framework má každý, kdo s PHP dělá aspoň rok? Čistě pro inspiraci, vážení.

Když jsem připravoval "new FW" (to je provizorní označení pro tento článek, nemá to ani pracovní název), tak jsem vyšel z jednoduché úvahy: Na co to potřebuju?

Dělám rád malé webové služby. Některé jsou už dávno pod drnem (trackref, hotlinks, notes), jiné se drží. Pokud chci nějaký běžný web s informacemi, tady obsah, tady galerie, tajhle články, tam aktuality, tak použiju Drupal a nemažu se s tím. Ale pokud chci udělat malou webovou službu, musím si ji napsat sám. Udělat vlastní "výkonné jádro" a nad ním postavit nějakou jednoduchou prezentační vrstvu – většinou nic velkého, třeba jen deset stránek. Jenže je tam spousta věcí, které se neustále opakují. Třeba "přihlášení / registrace". Nebo parsování URL. Nějaké rozumné webové API. Atakdále... Tudíž je ideální mít po ruce nějakou kostru a nějaké často používané části. A proč to nenazvat honosně frameworkem? :)

Chtěl jsem, aby to bylo malé, jednoduché a flexibilní. Uploadovat někam na server stovky kilobajtů frameworku, z něhož použiju desetinu schopností, to se mi fakt nechce. Taky jsem si řekl, že nepodlehnu mámení a nebudu chtít vyřešit VŠECHNO, co bych vyřešit mohl, ale jen to, co potřebuju. A rozhodně jsem nechtěl vymýšlet kolo, takže jsem spíš šel cestou: "Když je na to knihovna s vhodnou licencí, tak ji použiju a napíšu si jen fasádu, aby to bylo konzistentní" a "když je osvědčený způsob, použiju ho". Na druhou stranu byly věci, které jsem ve frameworku ošetřit chtěl:

- Architektura MVC. Je to už hodně profláklé, já vím, ale dobře se s tím dělá. Na druhou stranu nechci žádné složitosti: neřešit to co řešit nemusím! S tím souvisí i přístup Convention over Configuration, který jsem shledal jako velmi rozumný. Není důvod, proč by se například přihlašování jednou mělo odehrávat jako /Login, jindy jako /user/login a ještě jindy jako, třeba, /prihlaseni. Stránky jsou v /pages, controllery v /controllers a třídy v /classes, není důvod, proč by to mělo být měnitelné. Pokud vy ten důvod máte, tak gratuluji.

- Už zmiňovaná práce s uživateli. Pokud vím, že budu nabízet možnost nějaké personalizace služeb nebo něco podobného, kde se mi vyplatí nabídnout možnost registrací, tak prostě jen vytvořím potomka třídy Auth a ošetřím to, co bude konkrétní aplikace požadovat nad rámec standardního "jméno+heslo".

- Registrace uživatelů je hezká věc, ale jsme v roce 2008, takže jsem si implementoval rovnou možnost přihlásit se pomocí OpenID nebo LiveID. V controlleru použiju prosté $userid=$auth->needLogin() a nemusím se o nic víc starat, pokud je uživatel přihlášený, dostanu jeho ID, pokud není, tak ho  framework nechá přihlásit a pošle ho znovu na požadované místo.

- A když už jsem v tom, tak třeba taková reCaptcha se bude hodit, proto je fajn mít ji po ruce.

- Máme ten rok 2008 a za oknem Web2.0, takže bude fajn zaintegrovat nejen XML-RPC, ale i SOAP, REST a AMF. U malých webových služeb budou rozhodně užitečnější než třeba, cojávím, ORM.

- S čímž souvisí třeba i zmiňované zálohování dat na box.net nebo snadné posílání zpráv na mikroblogy. Do obecného frameworku by to samosebou nepatřilo, ale tohle jsou webové služby, tam "sa to zíde".

- Bez ohledu na konkrétní službu se mi vždy hodí mít mechanismus pro práci se vzdálenými daty, a to jak klientskou stranu, tak stranu serverovou, snadno integrovatelnou se zmiňovanými REST a spol.

- Možnost spuštění více služeb na jedné instalaci frameworku. Kdo někdy zažil opruz s tím, že každý update musel nahrávat na několik míst (a to dokonce i v rámci jednoho serveru), tak pochopí.

- S čímž souvisí inteligentní deploy mechanismus. Tedy způsob, jakým se aplikace nahrává na server a jakým se dělají aktualizace. Ne že by FTP nefungovalo, což o to – funguje dobře. Ale přeci jen – když člověk uploaduje dvěstě malých souborů, tak si říká, jestli by nebylo lepší mít něco, co by nahrálo jeden jediný soubor, který by se na tom serveru zase hezky rozložil a nahrál na patřičná místa.

- Lokalizace. Vše budiž v gettext... Je to rozšířené, je to téměř standard, dobře se s tím pracuje, tak není třeba vymýšlet kolo. S minimálními náklady přináší celkem velký efekt.

- Cache. Nic extra sofistikovaného, stačí obyčejná rychlá malá jednoduchá cache, která, s prominutím, nezafláká filesystém tunou souborů, jak to umí třeba cache u GetBoo. Brr.

- Implementace systému událostí. Je příjemné pak poslat jen "událost: blabla" a nestarat se, co všechno mám zavolat a kde a jestli jsem includoval všechny potřebné soubory a jestli se něco někde nepotluče...

- Alespoň jednoduchý debugger, tedy spíš jen jednotný systém ladících výpisů a logování.

- Jednotné používání případných knihoven třetích stran. Například takové Texy – stáhnu si knihovnu, nahraju do /3rd/texy a napíšu k ní jednoduchý wrapper, který se postará o potřebné.

Na druhou stranu jsou věci, které nepotřebuju:

- Již zmíněný ORM. Nezlobte se na mne, ale na malé služby s pěti tabulkama je nějaký velký ORM vysloveně nanic. Databázovou tabulkovou abstrakci prosím, ale netřeba ji řešit nějakým Propelem či něčím podobně ohavným.

- Databázový layer pro dvacet různých DB. U webových služeb neužitečné, v praxi se ukázala podpora MySQL, SQLite a ukládání do souborů jako dostatečná.

A některé věci neřeším do důsledků, jen lehce načrtávám:

- Šablonový systém. Mám wrapper pro Smarty a pro svůj jednoduchý šablonovač, a když na to přijde, dopíšu si wrapper pro cokoli jiného, ale myslím, že na to nepřijde. Přinejhorším mohu vždy použít PHP šablony.

- Vizuální stránku. Rezignoval jsem na vytváření HTML komponent. U malých služeb nejsou tak kritické, naopak je lepší mít vyšší míru flexibility v HTML kódu, u větších služeb použiju klidně ExtJS2 knihovnu, ostatně k tomu mám připravené eventy a persistentní objekty. A venkoncem nemusím být omezen jen na web a HTML, mohu použít Flex, AIR, OpenLaszlo, mohu vytvořit .NET desktopového klienta... Tohle framework pro malé webové služby dle mého názoru nemusí řešit, stačí jen když nabídne mechanismus pro snadnou integraci a jasné API.

---

Já vím, ten Váš Oblíbený to není a jistě se najde spousta objektivních důvodů, proč bych se na to měl vykašlat a použít Ten Jediný Framework (tedy ten, co se líbí vám, ofkoz). Jako bych ty komentáře viděl!

Upřímně řečeno, pokud chcete zasáhnout do soutěže o Křišťálovou Lupu, tak pravděpodobně využijete některý z velkých frameworků, PEARem počínaje přes Prado či Symfony až k Zendu, to jsou frameworky ideální pro Freemail roku, e-shop, web veřejné správy či vyhledávač. Pokud ale na slávu na poli českého internetu rezignujete a chcete udělat jen webovou službu či něco podobného dvanulovitého, tak, myslím, budou vaše požadavky podobné těm mým.

PS: Můj framework bude časem možná k dispozici, pravděpodobně ale ne veřejně ani komunitně, nehodlám opakovat Davidovu chybu s Nette. ;) Spíš bude jen na požádání a striktně pod licencí DPL. :) Ale sem tam nějakou zajímavou část či knihovnu jistě zveřejním.

PPS: NO FLAME!

Dne 20.08.2008

Twittni

Přidej do: Přidat na Conota Linkuj si ! asdf.sk StumbleUpon Toolbar Stumble It!

Komentáře

[1] (Lokutus - WWW) 20.08.2008, 21:17:14 [X] [D]
A když nemám vlastní PHP framework, nýbrž jen Lotus Notes framework, počítá se to taky?

Jinak já udělal tu zkušenost, že si to raději napíšu sám, než abych se učil cizí výtvory a snažil se pochopit, co tím autor myslel. Každý dobrý framework je beztak malý, pružný a psaný na tělo autorovi. Ty ostatní se snaží být obecné, všeobjímající a člověk má pocit, že by mohly řídit i odlet raketoplánu. Dokumentace k takovému dílu je pak obsáhlá jak román Vojna a mír.

No a protože i ten můj fw je psaný na tělo mně, mým potřebám a mému způsobu vývoje, tak ho ani v nejnovější "fuckt vymazlené" verzi asi nedám k dispozici. Nechce se mi totiž psát dokumentace.

[2] (Arthur Dent [openID] - Mail - WWW) 20.08.2008, 21:21:30 [X] [D]
[1] Asociace s tím raketoplánem: "Vojna a MIR" :)

Jo a dokumentace, to je přesně ten důvod. Něco málo píšu sám sobě, abych věděl, až se k tomu za půl roku vrátím, ale hlavní důvod, proč se tu o tom šířím, je, jak jsem psal, inspirovat další.

Ono třeba to OpenID není vůbec těžké implementovat. A přitom to je šikovná věc, jen stačí nedat na kydy neználků z Lupy (viz http://jdem.cz/ab243)

[3] (zlosyn - Mail ) 20.08.2008, 21:29:46 [X] [D]
Tak když máš dostatek elánu to vyvíjet a udržovat tak proč ne. Já už se svojí linejjakoprase vlastností dospěl k tomu, že si radši zaplácam disk obskurníma frameworkama ...a ať si je to třeba dvakrát pomalejší, jen když to budu mít co napsaný nejdřív :)

[4] (Arthur Dent [openID] - Mail - WWW) 20.08.2008, 21:32:38 [X] [D]
[3] No, když máš čas se to učit a ztrácet nervy s tím, že je něco jinak než jak bys to potřeboval... :)

[5] (zlosyn - Mail ) 20.08.2008, 21:33:44 [X] [D]
[2] je a neni, pokud to clovek neimplementuje primo z nejakyho guide for complete idiots tak u toho musi dokonce premejslet !!!

[6] (Arthur Dent [openID] - Mail - WWW) 20.08.2008, 21:42:29 [X] [D]
[5] ... a pokud to člověk implementuje přímo z technické dokumentace a píše "na zelené louce", tak se z toho akorát tak posere. Když ne při implementaci, tak nejpozději ve chvíli, kdy zjistí, že už to jiní udělali za něj. :)

[7] (danaketh - Mail ) 21.08.2008, 08:40:58 [X] [D]
Taky používám vlastní framework. Mám v něm jen to co potřebuju je to úplně malinká věc. Ikdyž pro nezúčastněného by mohl mít náhled do kódu smrtící účinky :) Zastávám názor, že co si můžu napsat sám, to si taky napíšu, protože vím jak to pracuje, co to dělá/nedělá, kde je jaká díra atd. A u implementace cizích věcí si nejprve prohlížím daný kód abych zjistil, jestli náhodou jeho nasazením někde něco neposeru :)

Takže držím pěsti, ať se daří.

[8] (Roman - Mail - WWW) 21.08.2008, 09:01:00 [X] [D]
Tiez si robim vsetko sam. Zaklad (db tabulky) vznikol este v 2001 a odvtedy to viac menej len vylepsujem o veci ktore si vyziada vyvoj. Do editora contentu sa pridalo sa cacheovanie, meta tagy. Do tabulky mapy stranok zasa nejake zgrupovanie do skupin ci vypinanie linkov na neaktivne. V podstate na tom bezi zaklad kazdeho webu. Robim to viac menej kvoli tomu aby som mal po kontrolou zdroje a mal slobodu v tom ako sa to dalej bude rozsirovat, viem si vsetko ohnut kam treba. Kazdy web ma vlastnu zakladnu sablonu (uplne bez php) kde sa vkladaju veci do vyhradenych miest stylom {title} , {menu}, {content}, {news}.. a ak treba pridat nieco nove robi sa to modulmi {{nazov_modulu=parametre,oddelene,ciarkou~alebo~inym~oddelovacom}} napriklad taka {{gallery=nazov-galerie}}. Moduly su tak flexibilne ze mi v podstate postupom casu vznika kniznica modulov ktore uz len potom pouzivam v dalsich weboch. Samozrejme veci ako editor som bral uz hotove. Pouzival som fckeditor s vlastnym upravenym file managerom ale to uz som zrusil pretoze to bolo zbytocne velke a stale to generovalo hnusny kod, nakoniec som zrusil wysiwyg kompletne a v novych veciach som skusil Texy, funguje to uplne genialne. Rychlo sa s tym naplnaju veci a vsetky vynimky si vkladam modulmi. Napr {{obrazok=nazov.jpg~left~alt-text}}.

Na jednom shope s brachom Havranom davame drupal 6 a uz sa vyrojilo zopar veci ktore nemam pod kontrolou (pamatova narocnost, ak je vypnuta kes tak stranky generuje dost pomaly (v admine vzdy).. a tak. Ale vyskusame a uvidime.

[9] (Hellish - Mail - WWW) 21.08.2008, 10:02:55 [X] [D]
Nedávno jsem objevil PHP framework CodeIgniter (codeigniter.com) a právě nad ním dokončuji jeden web. Líbí se mi právě tím, že není zbytečně nafouknutý a práce s ním je poměrně efektivní.

[10] (Hever [openID] ) 21.08.2008, 17:25:37 [X] [D]
Je to pěkné shrnutí. Líbí se mi, že nepopisuješ vlastní fw, ale jenom jeho vlastnosti, pěkné pro inspiraci.

Samozřejmě jako každý jiný mám také něco takového svého, takže je spoustou věcí jsem si taky musel projít. Některým tvým pojmům teda nerozumím, ale což, každý nemusí znát všechno. (Zajímal by mě teda "inteligentní deploy mechanismus".)

Myslím, že nejpodstatnější je to jednotné po/užívání čehokoliv. To myslím přijde časem, až si to dané cokoliv vyzkouší několikrát v různých situacích, tak může "vytýkat před závorku".

K OpenID - pro věci, co žijí na internetu to myslím je dobré řešení, pro věci, které pracují především ve vlastní síti (nelíbí se mi to slovo, ale používá se pro to intranet) ... tam mi to stále vrtá hlavou. V případě výpadku internetu, by pak uživatel docela zbytečně nemohl aplikaci použít.

[11] (Arthur Dent [openID] - Mail - WWW) 21.08.2008, 17:59:17 [X] [D]
[10] "Inteligentní deploy mechanismus": Ukrutně a šíleně mě rozčilují dvě věci. Zaprvé to, když během práce zapomenu, co jsem všechno změnil a co všechno musím nahrát na server, a zadruhé to, když se FTP na desátém souboru zasekne a šmytec, že příliš mnoho požadavků... S oblibou to dělávají některé freehostingy, ale dokáže s tím zprudit i GoDaddy.

To první lze řešit utilitami typu "FTP Synchronizer", ovšem když FTP synchronizer narazí na problém číslo 2, tak je to opravdu situace k pomilování, kdy člověku tečou nervy, vteřiny ubíhají, Synchronizer je totálně rozhozen po půl minutě usoudí, že toho bylo dosti a že tedy vše zkusí znovu, pak zjistí že byl mezitím odpojen, pak... Uch, darmo mluvit. Soustředění je v tahu a člověka taková práce akorát enervuje (čti: sere).

Deploy mechanismus, neboli "mechanismus umístění" (míněno "umístit na server") je taková věc, co umožní jednoduše to, co mám na PC, šoupnout na server s minimem vztekání a s minimem práce, pokud možno i rychle. V kostce: Mám na to skript, který se koukne jaké že soubory jsou v zadaném adresáři, vyhází z nich ty z ignore listu a spočítá si jejich hashe. Pak se zeptá serveru, jaké hashe mají ty soubory, co jsou tam. No a ty, které byly změněné, vezme, zaZIPuje, pošle na server a tam to kolega skript rozbalí a nahraje kam je potřeba. Okořeněno o výdobytek "nahrávat jen to co se změnilo od poslední synchronizace". Přenáší se míň dat, otvírá jen jedno spojení a je to i rychlejší. Kdo nevěří, nechť si zkusí uploadnout FTPkem 10 souborů po 20kB a jeden 200 kB.

Aktualizace příjemné, volání přímo z Eclipse jednoduché. (Někteří lidé tvrdí, že Eclipse / Aptana umí FTP synchronizaci, při bližším zkoumání jsem dospěl k závěru, že se tito lidé mýlí.)

No a OpenID na interní síti, to je buď za A zbytečné (identity uživatelům přeci přiřazuje nějaký správce), nebo za B možné, ale pak je jednodušší a logičtější spustit vlastní OpenID server v rámci oné sítě, ne? A pokud to je něco "většího", tak určitě existují mechanismy jak OpenID server může autentifikovat proti LDAP či tak něco... Ale osobně bych to asi na interní aplikace nedával.

[12] (Hever [openID] ) 21.08.2008, 18:49:38 [X] [D]
[11] OpenID - to je myslím správná úvaha.

Deploy mechanizmus se určitě vyplatí ... teda především tam, kde je spousta souborů a spousta adresářů.

Nevím jestli se mám ptát dál ... ale zajímalo by mě, kde jsou používány události (možná si jenom pod tím názvem nevybavím co bych měl).

[13] (danaketh - Mail ) 21.08.2008, 19:10:47 [X] [D]
[11] Na serveru kde běží projekty našich klientů mám na tohle rsync, protože ten server sám spravuju. Ten synchronizuje všechny projekty z jiného serveru, kde mám SVN. Z toho bych se odvážil vycházet a když už o tom tak přemýšlím, zkusím vymyslet jak to jednoduše a hlavně úspěšně implementovat.

Není to úplně to o čem mluvíš ale mohlo by to posloužit stejně. Frameworku sdělíš kam si má sáhnout pro aktualizaci čeho (tzn například má aktualizovat projekty X a Y) a on se sám postará. V tuhle chvíli přichází na řadu o čem hovoříš - kontrola hashů a podle nich updatování jen toho co je změněno.

Ale tohle řešení je nepoužitelné pokud se framework nemůže přihlásit k PC na kterém děláš, takže vlastně k ničemu :)

[14] (karmi - Mail - WWW) 22.08.2008, 10:10:22 [X] [D]
"Inteligentní deploy mechanismus -- Podívejte se sem: http://www.capify.org/, http://www.simplisticcomplexity.com.... Zmínky "o synchronizaci pomocí FTP" mně zas po dlouhé době docela vyděsily.