PHP Session beállítás

Rég óta egy keretrendszert használok, ahol eddig nem volt gond a session kezléssel.
Most ezt a rendszert kell egy új szerveren használnom, melyet nem én felügyelek, nincs hozzáférésem.

A sessiont oly' módon használom, hogy a sessionbe saját objektumot helyezek el, és minden sessionben tárolni kívánt változómat ez ez objektum tárol. A folyamat elején lekérem az objektumot a sessionből. Ha egy értéket meg akarok változtatni, akkor az objektumban átírom, majd visszarakom az objektumot a sessionbe. Ha nem rakom vissza az objektumot akkor nyilván a megváltozott érték sem tárolódik el.

Tehát:

function getObjectsFromSession(){
$ObjectsFromSession=new SessionHandler();
$temp= $ObjectsFromSession->getObjectFromSession("ph");
if (get_class ($temp)=="PropertyHolder"){
$this->ph = $temp;
}
}
Ekkor a "$this->ph" ban van minden.

majd megváltoztatom az objekutm egy elemét:
$this->ph->setProperty("változó_neve","változó_értéke");

Végül visszateszem a sessionbe:
function putBackObjectsToSession(){
$ObjectsToSession=new SessionHandler();
$ObjectsToSession->putObjectToSession("ph",$this->ph);
}

A gondom az, hogy ha az új szerveren nem hívom meg a
putBackObjectsToSession() függvényt, akkor is eltárolódik a változó értéke a sessionben:
$this->ph->setProperty("változó_neve","változó_értéke");

Remélem érthető a problémám.
Kérdésem, hogy tudja -e valaki, hogy minek a hatására tárolódik el a sessionben a változó (még akkor is ha direkt módon nem írom vissza); és hogyan lehet ezt php-ben kiiktatni?

Hozzászólások

És ha teheted, ne tárolj objektumokat a $_SESSION tömbben, nem ajánlott.

Kérlek, segíts ezt megérteni, te hogy csinálnád? vegyünk is egy példát. Van egy webshop, ahol először is tárolni kell/érdemes a felhasználót. Kell tárolni egy "kosarat", amibe termékek vannak (ne bonyolítsuk túl), és mind a felhasználó, a kosár, meg a termékek is objektumok. Hogyan tárolod ezt a struktúrát?

session-onként egy fájl, és kérésenként az egy fájl elérési ideje jóval kevesebb, mint adatbázishoz kapcsolódni, a felesleges sessionok meg úgyis törlődnek, tehát a merevlemez mérete nem lesz a szűk keresztmetszet. jee-ben más a helyzet, mert ott a perzisztencia kontextus cacheli el az entitásokat pl, tehát nem kell kérésenként kiolvasni a db-ből. Tudom php esetén is van lehetőség a cachelésre, de sok jót eddig nem hallottam/tapasztaltam erről a területről. Szerintem mindenért a db-hez nyúlni nem egészséges.

Ha hostolt környezetben dolgozol, szinte kizárt, hogy a perzisztens kapcsolatok meg lennének engedve. Ezt a luxust csak akkor engedheted meg magadnak, ha egyedül laksz a szerveren. A prezisztens kapcsolatok ugyanis egy prefork MPM-mel per processz vannak, azaz ott marad a sok üres kapcsolat az egyik processzben miközben a másikon meg gyártódnak az új kapcsolatok.

kisebb weboldalak esetén akár teljesen mindegy, hogy fájlba vagy adatbázisba kerülnek-e a session adatok, mivel az adatbázis felé általában nem csak emiatt kapcsolódik az alkalmazás. tehát feltételezhetjük, hogy a kapcsolat már él, ezért nem kell ennek a kiépítési idejével számolni.

ellenben vannak szituációk, amikor érdemesebb megfontolni, hogy sqlite vagy mysql adatbáziban, netalán memcache-ben tároljuk. pl képzeld el, hogy több frontend szolgálja ki az adott lapot és loadbalancer dönt, hogy az adott kérés éppen melyikre esik be. ahhoz, hogy fájlba írjuk a session adatokat kellene egy közös nfs minden frontendre felmountolva - mert ugye mindegyiknek el kell érnie ugyanazt a fájlt. így már meglepően lassú is lehet a fájlkezelés.
de ha csak egy kiszolgálót nézünk sok kéréssel, akkor is mutatkozik teljesítménycsökkenés, méghozzá nem egyenes arányban a kérések számával - sajnos.

aztán itt még bele lehetne menni abba is, hogy mi van akkor, ha - teljesen jogosan - nincs sehová írás joga a webszervernek? ilyenkor nincs más választásunk, alternatív tárolót kell keresnünk a session adatoknak.

szóval a modnandóm lényege az lenne, hogy teljesen felesleges vitázni arról, hogy melyik megoldás is jobb/gyorsabb amíg a körülmények nem tisztázottak... aston martinnal sem indul senki a somogybabodi sár-rallyn, pedig biztos jó autó az is.

üdv,
bejglivel töltött sbalazs.

Mondandód lényegével egyetértek, és tényleg a pontos szitu ismerete nélkül felesleges ezen vitázni. És az is tény, hogy kapcsolódás nem csak emiatt van, de én csak arra akartam célozni, hogy (még ha van is db kapcsolat) minden objektumot mindig felépíteni db-ből tuti lassabb, mint eltárolni őket session-ben (tekintsünk el a clusterezett kiszolgálástól). Lentebb próbáltak meggyőzni, hogy nem jó session-ben objektumot tárolni, de a cikkekben említett problémákba nem futottam még bele, így semmi akadályát nem látom annak, hogy sessionben tároljam az objektumokat, ahelyett, hogy mvc keretrendszerben burekoló osztályokkal bohóckodjak egy vacak "kosár" miatt.

minden objektumot mindig felépíteni db-ből tuti lassabb
minden esetben fel kell építeni, függetlenül attól, hogy db vagy sem. alapértelmezetten az objektumok serializált állapotban kerülnek mentésre, majd a session_start() függvény hívásakor lesz a bináris stringből array, object, stb. nézz csak meg egy élő session file-t.

semmi akadályát nem látom annak, hogy sessionben tároljam az objektumokat
én nem olvastam a cikkeket, lehet, hogy ott is ezeket írják:

  • felesleges helyet foglal az osztály leírása
  • a session_start() előtt biztosítanod kell, hogy az osztály már include-olva legyen (autoload-olható osztályoknál talán nem)
  • a topiknyitó hozzászólás is az objektumok session-ben való tárolása miatt született, mivel akaratlanul megváltozik a $_SESSION tömb tartalma, holott látszólag nem is azt módosítjuk.

persze mindenki maga dönti el, hogy objektumként meni-e el, vagy tömbként, amit az objektum inicializációjakor ad át a konstruktornak.

sőt, a PHP lehetőséget ad arra is, hogy használjuk a __sleep() és a __wakeup() metódusokat, így elérhtjük, hogy ne foglaljunk felesleges helyet, és ha magunk serializáljuk az objektumot, a $_SESSION-ben stringként lesz tárolva.

szerk:
még valami fontos kimaradt a listából. ha az objektumod resource-t is tárol, például fopen() vagy mysql_connect() visszatérését. na akkor nem tudod eltárolni sessionben, kénytelen vagy újra inicializálni ezeket...

sbalazs.

Mondandód lényegével egyetértek, és tényleg a pontos szitu ismerete nélkül felesleges ezen vitázni. És az is tény, hogy kapcsolódás nem csak emiatt van, de én csak arra akartam célozni, hogy (még ha van is db kapcsolat) minden objektumot mindig felépíteni db-ből tuti lassabb, mint eltárolni őket session-ben (tekintsünk el a clusterezett kiszolgálástól). Lentebb próbáltak meggyőzni, hogy nem jó session-ben objektumot tárolni, de a cikkekben említett problémákba nem futottam még bele, így semmi akadályát nem látom annak, hogy sessionben tároljam az objektumokat, ahelyett, hogy mvc keretrendszerben burekoló osztályokkal bohóckodjak egy vacak "kosár" miatt.

Igen, de
1 ebben az esetben bukta, hogy a kosár egy objektum legyen, és bukta a "tiszta" oop, márpedig elég csúnyán néz ki egy mvc-s keretrendszerben
2 bonyolultabb struktúra esetén tök feleslegesen terheli a szervert a kérés, hogy minden-t mindig ki kell olvasni, főleg ha egy termék esetleg nem csak egy táblával dolgozik

van egy nagy osztályod. Pl egy excel file-t kezelő osztály. Ezernyi include-olt file-al, amik egyes tagfügvényekben vannak, neadj isten dinamikusan include-olod őket.
Na, ekkor probléma lehet szerintem, ha egy objektumot a sessionban tárolunk.

De tapasztalatom nincs, nem próbáltam, nem látok bele a php objektumkezelésébe.

De annak mi értelme, hogy húzol egy burkoló osztályt arra, hogy egy tömbből kiolvass/beírj adatokat? OOP ide vagy oda, semmi értelme.

Azzal se szoktam egyetérteni, hogy azért, hogy megfeleljünk az OOP-nek, a táblázatoknál példányosítsunk le minden egyes elemet, hogy aztán abból készüljön a táblázat. Valami normális nyelvnél kevésbé zavarna az ilyen, de PHP-ben iszonyú sok feles erőforrást el tudna vinni szerintem.

----------------
Lvl86 Troll

Bár részben egyet értek, a második felével vitatkoznék. Tényleg nem tűnik jónak, ha egy táblázat minden sora egy külön objektum, de:
* Lehet, hogy később bonyolódik a helyzet, és hasznos lesz
* Tudjuk, amit tudunk a korai optimalizációról
* És ha a mérés után is bebizonyosodik, hogy performance hit a dolog, akkor használjunk cachet. A sima html output remekül gyorstárazható, és a kód is "szép" marad.

NAGYON hasznos, hogy ha nem egy globális tömbbe irogatsz közvetlenül. Pl megteheted azt, hogy teljesen saját session handlert írsz, kidobva a PHP saját handlerét. Az erőforrásokra meg kérünk szépen méréseket, mert ez így nem releváns. Pár száz osztály példányosítása alig mérhető idő alatt végbemegy.

Pár száz osztály példányosítása, adatokkal feltöltése, ha az OOP mintát követjük, setterekkel/getterekkel csináljuk

vs.

*_fetch_row() által visszaadott egy dimmenziós tömb feldolgozása.

Ha ehhez neked mérés kell, hogy megjósold, melyik a lassabb PHP alatt, akkor szomorú vagyok. .NET/Java alatt meg merném engedni magamnak ezt a luxust (sőt, ott kell is), de PHP alatt nem, főleg, figyelembe véve, hogy mennyire komplex a jelenleg használt táblázatgenerálási metódus nálunk.

----------------
Lvl86 Troll

szia,
a kérdésedre a válsz az, hogy a $this->ph = $temp; sor nem másolja/klónozza le az eredeti objektumot, mindössze annyit csinál, hogy a $this->ph-t ugyanarra a memóriacímre teszi - referencia szerinti értékadás. ha megváltoztatsz valamit a $this->ph-ban, az megváltozik a $temp-ben is, ami pedig a $_SESSION változóban van. ami érdekes, hogy eddig vajon miért nem így működött... ::töpreng::

egyébként úgy tűnik, hogy zavarosak az elképzeléseid az OOP-t illetően. engedd meg, hogy segítsek: nem kell minden adatot objektumba ágyazva tárolni. sőt, tárolás esetén előnyösebb primitív típusokat használni asszociatív tömbbe ágyazva. Az OOP része ott kezdődik, hogy a session handler-ed kell, hogy olyan osztály példánya legyen, ami képes ezeket az adatokat betölteni és visszamenteni a session adatokat tároló konténerbe - legyen az fájl, adatbázis, memcache, stb.
ajánlom figyelmedbe a session_set_save_handler() függvényt a php manuálból, amivel olyan session kezelő osztályt állítasz csatasorba, amilyent csak akarsz.

kellemes, békés ünnepet kívánok minden fórumozónak.
sbalazs.

( s_balazs | 2009. december 25., péntek - 13:01 ):
session_start() függvény hívásakor lesz a bináris stringből array, object, stb. nézz csak meg egy élő session file-t.
@

Majdnem. A helyes megfogalmazas, hogy egyszeru - es nem binaris - stringbol lesz array, object, stb..

( s_balazs | 2009. december 25., péntek - 13:01 ):
a session_start() előtt biztosítanod kell, hogy az osztály már include-olva legyen (autoload-olható osztályoknál talán nem)
@

Ez igy van. Sot! Fontos kiemelni, hogy mindenhol ahol session hasznalat van includolni [includolodnia] kell az adott osztaly definiciojat [-nak], fuggetlenul attol, h az hasznalva lesz -e vagy nem [ez elegge eroforras pazarlo 'megoldas'].
Ellenkezo esetben definicio nelkuli automatikus peldanyositas Fatal Error eredmenyez. Ezert celszeru ugy menteni a sessionbe objektumokat, hogy elotte serializaljuk oket. Igy a session automatikus serializalasa mar az altalunk serializalt stringet fogja ismet serializalni [igy elkerulheto az automatikus peldanyositas].

( wladek1 | 2009. december 27., vasárnap - 11:30 ):
sessiont MEMORY tipusu táblában szokás tárolni; ott meg ugye eléggé másként néz ki az ilyesmi...
@

Ebben az esetben, hogy 'szokas' megvalositani a session adatokhoz valo hozzaferesek konkurenciakezeleset?

szerializacio binaris formaba: Igbinary

Igbinary is a drop in replacement for the standard PHP serializer. Instead of time and space consuming textual representation, igbinary stores PHP data structures in a compact binary form. Savings are significant when using memcached or similar memory based storages for serialized data.

Features

* Supports same data types as the standard PHP serializer: null, bool, int, float, string, array and objects.
* __autoload & unserialize_callback_func
* __sleep & __wakeup
* Serializable -interface
* Data portability between platforms (32/64bit, endianess)
* Tested on Linux amd64, Mac OSX x86, HP-UX PA-RISC and NetBSD sparc64

tovabbi reszletek itt

Behringer Zoltan