[PHP] Chování session

Webdesign, HTML, CSS, Flash, PHP, ASP, .NET, JavaScript. Kritika www stránek na Smetišti.

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod SigmaError 8. 9. 2016 22:40

Zdravím,

pro jednoduchost máme následující kód

Kód: Vybrat vše
<?php

session_start();

session_regenerate_id(true);

echo "output";

?>


Sessiony se normálně ukládají do složky tmp (pro testování používám balík xampp, ale děje se to i na ostrém serveru LAMP).

Problém nastane, pokud rychle dvakrát či vícekrát pp sobě dám refresh stránky. Pokud v častějších intervalech např. 2-3x za vteřinu dám refresh webu, původní session tam zůstane a vytvoří se nová ačkoliv je nastaven parametr u regenerate na true. Je nějaká možnost jak tomuto chování zabránit?
SigmaError
Junior

Odeslat příspěvekod Pavel Černík 9. 9. 2016 09:43

Ano, děje se to a je potřeba pochopit proč. Zkusím to popsat jak to funguje na mírně upraveném příkladu:
Kód: Vybrat vše
<?php
file_put_contents('log.txt',"\n pozadavek ID: ".$_COOKIE['PHPSESSID'],FILE_APPEND);
session_start();
file_put_contents('log.txt',"\n nacteno ID: ".session_id(),FILE_APPEND);
file_put_contents('log.txt',"\n nactene data: ".$_SESSION["cas"],FILE_APPEND);
session_regenerate_id(true);
file_put_contents('log.txt',"\n znovuvytvoreno ID: ".session_id(),FILE_APPEND);
$_SESSION["cas"] = microtime(true);
file_put_contents('log.txt',"\n ukladane data: ".$_SESSION["cas"],FILE_APPEND);
sleep(1);
die('done');
?>

(sleep tam je proto aby načtení stránky trvalo déle a dalo se to jednodušeji testovat - máte pak celou sekundu na to abyste poslal nový request)


Když stránku párkrát obnovíte (rychleji než se sama stihne načíst) a podíváte se do log.txt tak uvidíte skutečný průběh:
Kód: Vybrat vše
pozadavek ID: pjjal8le841itaae59ikvf9fb1
nacteno ID: pjjal8le841itaae59ikvf9fb1
nactene data:
znovuvytvoreno ID: elfk45c0mrgccc5crv4il3pol4
ukladane data: 1473406560.3912
pozadavek ID: pjjal8le841itaae59ikvf9fb1
nacteno ID: pjjal8le841itaae59ikvf9fb1
nactene data:
znovuvytvoreno ID: 0ojjbmplmgbhkpa18mf87jh233
ukladane data: 1473406560.6363
pozadavek ID: pjjal8le841itaae59ikvf9fb1
nacteno ID: pjjal8le841itaae59ikvf9fb1
nactene data:
znovuvytvoreno ID: 2ngttt5nnvsg1b6fgr7jcq2ka5
ukladane data: 1473406560.8768
pozadavek ID: pjjal8le841itaae59ikvf9fb1
nacteno ID: pjjal8le841itaae59ikvf9fb1
nactene data:
znovuvytvoreno ID: 54voj9o6fofauotf677thkk2c5
ukladane data: 1473406561.1243

1 request (obsahuje session A) -> otevření souboru A -> smazání souboru A -> průběh zbytku skriptu (čekání) -> při ukončení uložení souboru B a poslání ID B klientovi
2 request (stále obsahuje session A, klient zatím neví o session B) -> soubor A neexistuje -> generuje se soubor C -> .... -> klient se dozvídá o session C.
Je zřejmé že při takovémto průběhu nikdy nedojde k requestu obsahujícímu session B a takový soubor zůstane přítomný a nedojde k jeho smazání.
Dá se to přirovnat k situaci, kdy se k vám přihlásí člověk, poté smaže cookies, přihlásí se znovu, opět smaže cookies a opět se přihlásí. Pak tam budete mít 3 soubory s tím že o 2 z nich již nikdy nikdo nepožádá (a tak nebudou ani smazané) protože jde v podstatě o "sirotky".
Takové soubory může smazat jen automatický garbage collector, který by snad na každém serveru měl být automaticky a který po čase sessiony maže sám.
Pavel Černík
Junior

Odeslat příspěvekod SigmaError 9. 9. 2016 10:41

Díky moc za vyčerpávající odpověď. Použití GC mě napadlo, ale chtěl jsem se ujistit, že nedělám někde chybu já.
SigmaError
Junior

Odeslat příspěvekod karlos00x 9. 9. 2016 11:33

nevim jestli spravne chapu na co se ptas, ale mozna je to tato nastaveni:
session.gc_divisor 1000 1000
session.gc_maxlifetime 1440 1440
session.gc_probability 1 1

http://php.net/manual/en/session.configuration.php
a tady i nejaky detailni povidani: http://stackoverflow.com/questions/1516 ... ssion-last
Upgrade který má smysl: SSD. Zažijete svižný počítač.
karlos00x
Pokročilý

Odeslat příspěvekod SigmaError 9. 9. 2016 12:59

Ve výsledku se jedná pouze o nastavení GC.

Protože pokud jsem tomu porozumněl správně, tak skript který vícekrát za krátký časový úsek refreshuji, tak se nestihne dokončit a tím pádem vzniká session "sirotek", na kterou už nevede žádná cesta jak s ní pracovat. Takže jediná možnost jak to řešit je nastavení GC na nižší časový úsek, kdy vymaže sessiony, které už nejsou používány.
SigmaError
Junior


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků