Többlépcsős folyamat leprogramozása PHP-ban
Sziasztok!
A többlépcsős folyamat alatt egy olyan oldalt értek, mint pl amikor megrendelsz egy webáruházban egy terméket. A következő lépéshez szükséges az előző lépés teljesítése. Az ilyen folyamatokhoz, legyen az bármi, még egy ábrát is mellékelnek, hogy éppen melyik szinten vagy miközben megmutatják hogy milyen szinteken vagy túl és milyen szintek állnak még mögötted.
Lehet hogy én bonyolítom túl a dolog, nekem egy termék kosárba helyezéséhez kellene egy ilyen több lépcsős folyamat. A termék tulajdonságait kell beállítani az egyes szinteken és ha mindent beállított a felhasználó akkor bekerül a kosárra.
Úgy gondolom, hogy biztos van az ilyen jellegű problémák megoldására egy bevált módszer és ezt szeretném megkérdezni hogy mitévő legyen ilyen helyzetben. Engem tulajdonképpen az elv érdekelne, vagy ha valaki ismer egy jó leírást az interneten azt is megköszönném.
Előre is köszönöm!
■ A többlépcsős folyamat alatt egy olyan oldalt értek, mint pl amikor megrendelsz egy webáruházban egy terméket. A következő lépéshez szükséges az előző lépés teljesítése. Az ilyen folyamatokhoz, legyen az bármi, még egy ábrát is mellékelnek, hogy éppen melyik szinten vagy miközben megmutatják hogy milyen szinteken vagy túl és milyen szintek állnak még mögötted.
Lehet hogy én bonyolítom túl a dolog, nekem egy termék kosárba helyezéséhez kellene egy ilyen több lépcsős folyamat. A termék tulajdonságait kell beállítani az egyes szinteken és ha mindent beállított a felhasználó akkor bekerül a kosárra.
Úgy gondolom, hogy biztos van az ilyen jellegű problémák megoldására egy bevált módszer és ezt szeretném megkérdezni hogy mitévő legyen ilyen helyzetben. Engem tulajdonképpen az elv érdekelne, vagy ha valaki ismer egy jó leírást az interneten azt is megköszönném.
Előre is köszönöm!
Munkamenetkezelés
Ha helyesen tölti ki a tulajdonság formot akkor ezt valamilyen változó segítségével beállítod a SESSION-ben, és csak akkor engeded tovább ha ez megvan, egyébként nem. Minden lépésnél az aktuális lépéshez tartozó scriptben ellenőrzöd hogy az előző lépéseknél rendben volt-e minden.
temp tábla
re: temp tabla
Nem csináltam
Én sem
A temp tábla csak egy adott db connection érheti el. A phpben nem tudod ezt a connectiont továbbadni, tehát el fog veszni a táblával együtt.
Nyilván a sessionben kell tárolni az egyes tulajdonságokat, meg hogy éppen hányadik lépésnél tart a júzer, mert két kérés között az az egyetlen tárolási forma.
Hmm egyébként elgondolkodtam azon, hogy a sessionjeimet memcache-ben tároljam adatbázis helyett, bár onnan elég nehézkes a listázás.
DOS
Az adatbázis a barátod, de csak ha jól használod. Hetente takarítok olyan felhasználók után, akik indexek nélkül tartják a tábláikat és mindenféle temptábla-varázslásokat követnek el. Ilyenkor aztán repül a letiltás. :)
Félreértesz
A másik pedig, hogy elképzelhető a php session paramétereinek tárolása adatbázisban is. Ez mondjuk csomó kézi dolgot automatizál. Döntés kérdése, hogy sessionben vagy db-ben tárolja, csak felvetettem, ha plusz egy megoldási mód kellene.
Ok
Azt a mondatodat sajnos nem értem, hogy a session DB-ben tárolása mit automatizál a filehoz képest, magyarázd el légyszi.
időeltolódás a lépések között
Ez igaz
Pont, hogy nagy terhelésre jó
Hol olvastad?
Egyébiránt nem kötelező a filerendszer sem (vagy írtam volna ilyet?) tarthatod memcacheben is pl. Egy napi 35k látogatójú portál session adatai elférnek 100 megában.
Ezzel szemben 10k bejegyzéssel a MySQL valóban jól elvan, viszont kénytelen vagy minden oldalletöltéskor írni bele hogy ne évüljön el a session, na az viszont már kicsit jobban fáj.
Hát
Az adatbázisnak viszont az az előnye, hogy aktív sessionnel rendelkező emberkék jogait realtime módosíthatod az admin felületről, plusz csinálhatsz egy szép rendezett listát az aktív userekről. Kérdés, hogy megéri e :-)
Ha a db terheltségére gondolsz, akkor ebből a szempontból valóban fájdalmas lehet.
DB vs file
Session adatbázisban
Ha mondjuk admin oldalról meg akarom keresni egy adott user sessionjét, akkor csak egy select kell a sessions táblára, és nem kell a fájlok között keresgélnem.
Persze
Tetszik
szerk:
Közben ki is gondoltam, hogy a táblába a sessionid meg az userid kerül majd, meg egy módosítási dátum, amit a garbage figyel, és 10 percenként frissít a memcacheből.
A memcacheben a sessionid lesz az azonosító, és elég sok dolog bele fog kerülni.
A szemétgyűjtés persze megoldható tábla nélkül is, a táblának igazából az a funkciója, hogyha csinálok admin oldalról egy lekérést, akkor össze lehessen párosítani az useridket a sessionidkkel, és ha létezik a módosított userhez session, akkor a memcache kapjon egy értesítést arról, hogy frissítenie kell valamilyen adatot.
Arra gondoltam, hogyha valaki elkezd írni egy cikket, akkor a piszkozatot a memcache-be mentem néhány percenként, aztán ha elkészültek kerülnek be a megfelelő táblába. A garbage meg törlés előtt megnézi, hogy van e ilyen piszkozat a sessionnél, és ha van, akkor menti a piszkozatos táblába, hogy később lehessen folytatni. Ez pl sztem tökjó, ha valaki ottfelejti az írását a gépnél, vagy hosszú cikket ír, és sokáig nem aktív.
(Az automata mentést meg megcsinálom úgy, hogy csak akkor fusson le, ha gépelt is valamit az illető.)
Szóval tetszik az ötlet, bár még nem értek a memcache-hez, de gondolom több időt fogok a telepítéssel tölteni, mint ami alatt megtanulom. :-)
Memcache
Másik ötlet: vegyél föl reverse rekordokat a memcachebe.
PL 'user_joskapista' => array('a5fdsadar3ada').
Még talán listázni is tudod a memcache kulcsokat getExtendedStats()-al.
Ami a memcachet illeti, minden normális Linuxon van csomagban, Windowson meg nem szeretnél PHPt üzemeltetni.
Ehm
Egyébként kb úgy csinálnád, mint én.
Vannak olyan dolgok ezek szerint, amiket érdemes a sessionbe gyűjteni, és csak a session lejártakor hozzáadni az adatbázishoz. Így nem lassítják a lekérdezést.
Pl. history-nél ha loggolni akarok minden aktivitást, akkor memcacheben gyűjtöm, és a végén adom a dbhez, így nem lassítom a lekéréseket azzal, hogy minden alkalommal db-t frissítek.
Online szerkesztés
Vim
Kösz
Én mondjuk NetBeans-el foglalkoznék szívesen, mert az java-nál elég elterjedt, így elég csak egy helyen megtanulni a kezelését, másrészt NetBeans sok másik nyelvhez is van, nagyon nagy project, így biztos, hogy nem áll le a fejlesztés php terén sem, sőt valszeg gyorsabb lesz, mint az összes többinél.
Ezek szerint az egyedüli, ami igazán kiforrott php szerkesztők terén az a Komodo. Még agyalok rajta, hogy ilyenbe belefogjak, mert azért nekem már megvan az ugyan elavult, de biztonságos módszerem :D Leginkább az érdekel, hogyha bármi kánya van a szerverrel, akkor az itthoni gépemen legyen egy biztonsági mentés arról, amivel eddig dolgoztam. Ha ilyen tükrözést is be lehet lőni rajta, akkor szívesen megnézem, amúgy nem érdekel annyira.
Egyébként kicsit elkanyarodtunk az eredeti témától, de ez kifejezetten tetszik. :-) Legalább nem olyan sablonos a fórum felosztása, mint prog.hu-n.
Fejlesztés
A loggolásra meg ott a syslog, kár erölködni vele. DB-ben nem érdemes loggolni, főleg nem realtime. User interakciókat talán, bár kétséges hogy kell-e.
Ez azért nem ilyen egyszerű
Szal egyelőre nekem ez így kényelmesebb, mint az online szerkesztés. Majd ha eljutottam abba a fázisba, hogy már lehet tesztelni, akkor felteszem a szerverre és ráengedek párszáz ismerőst tesztelőnek, szóval majd akkor foglalkozom a dologgal, amikor itt az ideje.
szerk:
Ok, nem szóltam :-)
Egyrészt lehet online szerkeszteni godaddynél, másrészt lehet írni a php.ini-be. Meg úgy összességében nagyon komoly az oldal. (Az egyedüli, amit hiányolok belőle, az a notepad++, nincs kódszínezés, ha tab-ot nyomok, akkor focust vált, etc.)
Off: Ójaj...
:-)
Egyelőre csak tanulgatom, hogy kell komolyabb oldalakat csinálni. Ha nem így lenne, akkor fix, hogy nem a php-t választom, hanem jsp-t vagy asp.net-et. Ha befut az aktuális oldal, akkor előbb-utóbb újraírom komolyabb nyelven is, mert sokkal gyorsabb, ha nem kell minden lekérésnél újraépíteni az objecteket.
Egyébként ha valaki adatbázisból vagy memcachedből akar sessiont kezelni, akkor előbb nézze meg ezt a linket, mert ezzel kapcsolatban van egy elég idegesítő bug a php-ben, amit évek óta nem javítottak.
Jajj...
Ja egyébként ez nem bug, ez design döntés. session_write_close meghívása destruktorban a barátod.
Ohh..
Destruktor helyett inkább ezt használom:
Még a session_id generáltatást kell átírnom benne, a szemetet meg rohadtul nem ő fogja kezelni. Szóval alakul a session kezelésem. Azt hiszem jót tett, hogy pár hónapot oop meg refactoring olvasgatással töltöttem, mert most elég könnyen megy a fejlesztés. Csak azt kell átgondolni, hogy milyen feladat melyik kategóriába menjen (mvc), a többi meg már jön magától.
+1 kis kiegésztéssel
+1
miért?
Mellesleg megjegyezném, hogy a lesajnált PHP saját session kezelője pl. figyel a kölcösnös kizárásra (pl. ajax kérések esetén érdekes lehet), amire egy saját cucc jóformán sohasem szokott.
Nem voltam pontos
Ami a saját session handlert illeti, lehet abból jót írni, nem feltétlenül ramdiskre, de pl a memcache most már tud redundanciát, stb. szóval ha nagyon akarod, lehet abból jót csinálni. Persze érteni kell hozzá, de ez meg nem újdonság. Azt meg, hogy hogy figyel a PHP saját session handlere egy random filerendszeren (NFS? GFS?) azért úgy megnézném közelebbről. Az mindenhonnan elérhető sessionök pedig ugye a clusterezhetőség alapvető követelményei.
Amit a destruktorral gondoltam, hogy a session osztály vagy a rendszer destruktorában (kialakítástól függően) hívjuk meg a session_write_close-t. A lényeg, hogy ott kell keresni a megoldást.
...
Valóban
Valóban, de a történelem beigazolta, hogy nem is volt szükség rá. Egyébként az egész session handler mágikus módon volt vagy 200 sor szóval semeddig nem tartott volna kicserélni, főleg hogy minden osztály a megfelelő API-n keresztül birizgálta.
Pont ilyen megfontolásból zártam le destruktorból a sessiont. Úgy 2 éve, amikor még a PHP sajátját használtam.
PHP bug
strace
Egyébként ha az ember nem is óhajt ilyesmibe belemenni, Windows alatt egy normális tail nincs (tudtommal), amivel rendesen lehetne realtime nézni a logot. Plusz a feldolgozáshoz kapcsolódó egyéb feladatokat sokkal nagyobb probléma tesztelni. Hogy mondjak egy példát, egy fejlesztőcsapatban kialakítasz egy struktúrát a cronjobok nyilvántartására, amit be is küldesz SVN-be. Ebből Linux alatt gyerekjáték a megfelelő crontabot előállítani, Windows alatt viszont szerintem egy vagon MSDN olvasás és guglizás befigyel. :)
Azt meg már csak úgy csendben jegyzem meg, hogy célszerű lenne az éles környezethez minél hasonlóbb környezetben fejleszteni, mert aztán jönnek a meglepetések. A PHP verziókülönbségek ilyen szempontból halálosak, de én a platformon is gondolkoznék.
akkor nem olyan gyakori
Memcache LRU, slab classes
A memcacheben a sessionid lesz az azonosító, és elég sok dolog bele fog kerülni.
És van még egy kevésbé ismert dolog: a memcache a számára adott memóriát fix méretű cellákákból álló lapokra osztja. Egy lapon belül a cella méret fix. Amikor leraksz valamit memcachebe, akkor megkeresi azt a lapot, aminek a cella mérete már nagyobb, mint a lerakni kívánt adat, és van még rajta üres hely. Ha nagyon össze-vissza méretű dolgokat tárolsz le memcache-be, akkor előfordulhat könnyen olyan eset is, hogy a különböző méretű lapok létrejöttével "betellik" a memcache számára adott memória, ezen lapok telítettsége viszonylag alacsony lesz, de ennek ellenére ha jön egy még nagyobb méretű adat, akkor már nem fogja tudni letárolni. Ez cache jellegű használat esetén is elég fájó, hiszen az adatok előállítását végző "drága" művelet le fog futni mindig, session jellegű felhasználás esetén meg végképp szívás. Ha számoli kell ilyesmivel, akkor érdemes a memcache indításakor a lehetséges legnagyobb méretű objektumot automatikusan letráolni.
Paraméterezés
Ami a slab méretet illeti: tekintettel arra, hogy egy session bejegyzés kb lóf/2 méretű szok lenni azért ennek kellene működnie. Persze aki eszetlen mennyiségű adatot akar benne tartani, az megérdemli. A rendszergazda meg egyeztessen a fejlesztőkkel (vagy fordítva) hogy mit szeretnének csinálni és legyenek úgy megcsinálva a szerverek, hogy működjön.
Ez az egész egy döntési kérdés, nyilván ez sem tökéletes, de szerintem annál, hogy NFS-en vagy adatbázisban tároljuk a sessionöket, jobb lesz. Igazából kellene erre valami normális, specializált backendet írni de az sok C kód gépelését jelenti.
Nemsokára migrálunk majd valószínűleg Memcachere aztán jól meglátjuk.
...
Ezt írta inf3rno:
Plusz indexes ismerős mesélte, hogy szívtak már memcache esetén a slab méretek miatt, szóval nem légből kapott probléma.
Félreértetted
Ami bekerül a munkamenetbe az egy átlag user esetén iszonyatosan kevés adat. Inkább az adminoknál van szó nagyobb adatmennyiségről.
Arról már letettem, hogy szöveget memóriába mentsek, mert perceket kéne várni a garbage-re, hogy lementse az adatbázisba a session lejártakor, és nem szeretném, hogy néhány percre eltűnjön valami, majd újra megjelenjen. A garbaget meg emiatt nem szeretném sűrűbben futtatni.
Ami sok lenne, és bekerülne az az admin tevékenységének loggolása, viszont adminból nincsen olyan iszonyatosan sok, és nem hinném, hogy ebből megabájtokat össze lehetne rakni. Ezeket a munkamenet lejártakor raknám csak be a db-be, hogy ne kelljen minden egyes admin tevékenységhez db kérést írni. Ehhez is lehetne valami limitet szabni. Mondjuk a session mentése előtt megnézném, hogy mekkora a session hossza, és ha túl nagynak ítélem, akkor beraknám db-be az adatokat.
Default slab-re azt írták, hogy 48byte kulcs+flag és 40 byte adat. Ha bekapcsolom a tömörítést a set-nél, akkor elvileg lazán belefér egy mezei user összes adata egy cellába, tömörítés nélkül meg úgy határeset. De ha két cellát foglal el, akkor sem igazán számít, mert közelében sincsen annak a nagyságrendnek, hogy gondot okozzon. Valszeg inkább 2 cella lesz a serialize miatt.
Van valamilyen tapasztalatod azzal kapcsolatban, hogy a tömörítés mennyire éri meg?
(Egyébként kösz, hogy szóltál, jó ha tágul az ember látóköre.)