Shkruani në sesionin php. Përdorimi i Sesioneve - Puna me Sesionet PHP

Ndërsa vazhdoni të mësoni PHP, ndoshta do të përdorni veçorinë e sesionit, ose të paktën do të dëgjoni për të herë pas here. Në këtë artikull do të flas për to në mënyrë më të detajuar dhe, duke përdorur shembuj ilustrues, do të analizojmë parimin e funksionimit të tyre. Unë gjithashtu do t'ju tregoj se ku dhe si mund të përdoren zakonisht.

Çfarë është një seancë? Sesionet ju lejojnë të krijoni një lloj lidhjeje midis vetë faqes dhe përdoruesit, duke përdorur një identifikues sesioni. Të gjitha variablat e sesionit dhe vlerat e tyre ruhen ekskluzivisht në server. Përdoruesi, si dhe serveri, ruan vetëm identifikuesit e sesioneve që krijohen në mënyrë të rastësishme, të njëjtat ju lejojnë të krijoni të njëjtën lidhje server-klient.

ID-ja e sesionit e ruajtur në anën e klientit (në kompjuterin e tij) është një skedar biskotë. Cookies ruhen në shfletuesin e përdoruesit, por skedari përkatës krijohet gjithashtu në server.

Le të shkojmë direkt në praktikë.

Ne krijojmë një seancë:

Mënyra më elementare këtu është përdorimi i funksionit session_start:

1 2 // Fillimi i seancës sesioni_fillimi ();

// Fillimi i sesionit sesion_start();

Ky funksion kontrollon nëse ka një identifikues sesioni, nëse jo, atëherë e krijon atë. Dhe nëse është i disponueshëm, atëherë ngarkon variablat e regjistruar nga sesioni ekzistues.

Një konstrukt i tillë duhet të thirret vetëm një herë për faqe dhe përpara çdo dalje (ky rregull vlen edhe për setcookie()).

Unë do të jap një shembull, kur një sesion krijohet në një shfletues, atëherë cookie atje ka formën e mëposhtme

Kur krijohet një sesion, një cookie e llojit të mëposhtëm "mbërrin" në shfletues:

1 2 jehonë "Emri i sesionit:". emri_sesionit(). " ID e sesionit: ". sesioni_id(); // Emri i sesionit: PHPSESSID ID e sesionit: mceu371l97id3sa0vcbjqnht06

echo "Emri i sesionit: ".sesion_name(). " ID e sesionit: ".session_id(); // Emri i sesionit: PHPSESSID ID e sesionit: mceu371l97id3sa0vcbjqnht06

Le të krijojmë një variabël sesioni:

Një variabël sesioni mund të krijohet duke shtuar një vlerë në elementin superglobal të grupit $_SESSION:

unset($_SESSION["identifikimi"]);

Metoda e mësipërme është e mirë, por ju mund të pastroni të gjithë grupin $_SESSION, kështu që ne do të heqim të gjitha variablat nga sesioni:

1 2 // Pastroni grupin tonë $_SESSION$_SESSION = grup();

// Pastro grupin tonë $_SESSION $_SESSION = grup();

2. Tani duhet të zhvlerësojmë cookie-n (ku emri i sesionit i referohet ID-së së sesionit në cookie dhe URL):

1 2 3 if (isset ($_COOKIE [sesion_emri () ] ) ) ( // session_name() - nxirr emrin e sesionit aktual setcookie (emri_sesionit () , "" , koha () - 86400 , "/" ); )

nëse (isset($_COOKIE)) ( // emri_sesionit() - nxirrni emrin e setcookie-it të sesionit aktual(emri_sesionit(), "", koha()-86400, "/"); )

3. Epo, atëherë do ta shkatërrojmë seancën (do ta mbyllim atë):

sesioni_fillimi (); ob_start();

Këtu është një shembull më i detajuar i kodit duke përdorur kodet dhe funksionet e diskutuara më parë:

1 2 3 4 5 6 7 8 9 if (isset ($_SESSION [ "login" ] ) ) ( jehonë "Përshëndetje, " . $_SESSION [ "emri" ] . " " ; unset ($_SESSION [ "login" ] ) ; if (isset ($_COOKIE [sesion_name () ] ) ( setcookie (emri_sesionit () , "" , koha () - 86400 , "/" ); // përmbajtja e sesionit tonë është një varg bosh) ob_end_flush() ; // Dërgo dalje në shfletues sesion_shkatërrim();

if (isset($_SESSION["login"])) (jehonë "Përshëndetje, " . $_SESSION["emri"] . " "; unset($_SESSION["login"]); if (isset($_COOKIE)) ( setcookie(sesion_name(), "", time()-86400, "/"); // përmbajtja e sesionit tonë është një varg bosh ) ob_end_flush(); // Dërgo daljen te shfletuesi session_destroy();

Megjithatë, vini re se përdorimi i funksionit ob_end_flush() nuk kërkohet gjithmonë. Dhe gjithçka sepse përkthyesi PHP pastron automatikisht buffer-in tuaj kur ekzekutoni një skript.

Le të rikrijojmë ID-në e sesionit:

Sa herë që identifikoheni, për arsye sigurie, është e nevojshme të rigjeneroni ID-në e sesionit. Të gjitha informacionet në variablat e sesionit tuaj ruhen në serverin tuaj të internetit në tekst të thjeshtë në një skedar specifik, të gjitha informacionet në lidhje me variablat e përdorura në sesion ruhen dhe vetëm ID-ja e sesionit ndryshon. Për të rigjeneruar ID-në e sesionit përdorni funksionin session_regenerate_id(), më pas rifreskoni faqen ekzistuese siç është bërë ose dërgoni përdoruesin në një faqe tjetër duke përdorur një ridrejtim.

Si funksionojnë seancat:

Në pamjen e mëposhtme të ekranit, mund të shihni një përmbledhje të vogël të vetë mekanizmit të sesionit.

Zvogëloni jetëgjatësinë e seancës:

Vlera e paracaktuar e jetëgjatësisë së sesionit është 0, që do të thotë se nëse përdoruesi mbyll dritaren e shfletuesit, sesioni gjithashtu do të mbyllet. Por ndonjëherë ekziston nevoja për të shkatërruar me forcë seancën e klientit pasi të ketë kaluar një kohë, për shembull, për shkak të pasivitetit nga ana e tij në sit. Le të analizojmë metodën e një zbatimi të tillë duke përdorur shembullin e autorizimit të përdoruesit: ne do të krijojmë një lloj ndryshoreje dhe do të ruajmë në të kohën e përdorur për të autorizuar përdoruesin, për shembull, nëse përdoruesi përpiqet të rifreskojë faqen, atëherë krahasojmë kohë me kohën që ai ishte joaktiv, dhe nëse është i këtij kufiri, do të dalë nga llogaria dhe do të dërgohet në faqen e autorizimit.

1 2 3 4 5 6 7 8 $_SESSION[ "fillimi" ] = koha() ; // Koha e fillimit kur përdoruesi është identifikuar$zone = koha() ; // Koha e dhënë (ajo që është tani)$time_limit = 2000 ; // Kjo është koha maksimale e pasivitetit të përdoruesit nëse ($timezon & gt; $_SESSION [ "fillimi" ] + $time_limit ) (echo "Koha ka mbaruar"; ) else ($_SESSION ["fillimi"] = koha () ;) // nëse gjithçka është në rregull, atëherë përditësoni

$_SESSION["fillimi"] = koha(); // Koha e fillimit kur përdoruesi hyri në $timezon= time(); // Koha e dhënë (që është tani) $time_limit = 2000; // Kjo është koha maksimale e papunësisë së përdoruesit nëse ($timezon> $_SESSION["start"] + $time_limit) (eko "Koha ka mbaruar"; ) tjetër ($_SESSION["start"] = koha();) / / nëse gjithçka është mirë, përditësoni

Ndonjëherë njerëzit kanë një pyetje "Si të zbatoni një jetëgjatësi të pafundme sesioni?", ja ku do ju jap pergjigjen. Kjo nuk duhet bërë, tashmë është e gabuar në rrënjë të idesë. Seanca jepet për këtë, në mënyrë që përdoruesi të hyjë në faqe - hapet, ai largohet - mbyllet (shkatërrohet). Kur ai shkoi përsëri, seanca hapi një të re. Megjithatë, është e mundur të përdoren të dhëna nga cookie-t për seancën, të cilat mund të ruhen për një kohë mjaft të gjatë, për shembull, kur përdorni kutinë e zgjedhjes "Më kujto" (Të kujtohet kjo në sajte?)...

Përdorimi i seancave me kuki të çaktivizuara:

Më thuaj kjo nuk ndodh? Mjerisht, kjo ndodh ndonjëherë. Për shembull, nëse vendosim session.use_trans_sid në 1, atëherë nëse nuk përdoret cookie, PHP do të kalojë parametrat PHPSESSID duke përdorur metodën GET në vargun tuaj të pyetjes.

Kjo është ajo, artikulli ka përfunduar. Nëse keni ende pyetje në lidhje me përdorimin e seancave, ose ndoshta ka disa shtesa ose komente, mund të lini gjithçka në komentet e këtij artikulli.

Që në fillim, PHP u pranua me zhurmë, por sapo filluan të krijohen projekte mjaft të mëdha në këtë gjuhë, zhvilluesit u përballën me një problem të ri - nuk kishte asnjë koncept të variablave globale në PHP! Kjo do të thotë, një skript i caktuar u ekzekutua, u dërgua faqja e gjeneruar te klienti dhe të gjitha burimet e përdorura nga ky skript u shkatërruan. Më lejoni të përpiqem të ilustroj: supozoni se ka dy faqe të së njëjtës faqe, index.php dhe dothings.php. Kodi burimor për këto faqe duket si ky:

indeks.php gjërat.php

Nëse i ekzekutojmë këto dy skripta, atëherë në faqen e parë do të shohim mbishkrimin "Më kërkuan të index.php", dhe faqja e dytë do të jetë bosh.

Zhvilluesit e faqeve të internetit, pa u menduar dy herë, filluan të përdorin cookie për të ruajtur variabla globale në anën e klientit. Procesi dukej diçka si ky: një përdorues vjen në faqen kryesore të faqes, kryen disa veprime dhe të gjitha informacionet në lidhje me këtë përdorues, të cilat mund të kërkohen në faqet e tjera të faqes, do të ruhen në shfletuesin e tij në formën e një cookie. Kjo metodë ka të meta mjaft serioze, për shkak të të cilave shumë zhvillues ia kthyen shpinën PHP-së në të njëjtën kohë. Për shembull, ne duhet të autorizojmë një përdorues që t'i lejojë atij akses në seksionet private (ose në pronësi vetëm të tij) të faqes. Ju do të duhet t'i dërgoni përdoruesit një cookie, e cila do të shërbejë si identifikues i tij i mëvonshëm në sit. Kjo qasje bëhet shumë e rëndë dhe e papërshtatshme sapo faqja fillon të mbledhë gjithnjë e më shumë informacion në lidhje me sjelljen e përdoruesit, sepse është e dëshirueshme që të kodohen të gjitha informacionet që i dërgohen përdoruesit në mënyrë që të mos falsifikohen. Kohët e fundit, një cookie e rreme mund të "fusë" më shumë se një bisedë, dhe ndonjëherë edhe të futet në postën e dikujt tjetër. Për më tepër, ka ende njerëz të çuditshëm në botë, shfletuesi i të cilëve nuk mbështet cookies.

Unë nuk do të hyj në çështjet teknologjike të mekanizmit të sesionit, por do të përshkruaj vetëm se si të punohet siç duhet me sesionet në PHP.

Si të punoni me sesione?

Nëse testoni shembujt nga artikulli (ose skriptet tuaja) në disa pritje komerciale, nuk duhet të ketë probleme me punën me seancat. Nëse e konfiguroni vetë serverin tuaj (qoftë ai një server i vërtetë ose një emulator), mund të shfaqen gabime si ky:

"Paralajmërim: open(/var/state/php/sess_6f71d1dbb52fa88481e752af7f384db0, O_RDWR) dështoi: Nuk ka skedar ose drejtori të tillë (2)".

Thjesht do të thotë që ju keni konfiguruar gabimisht PHP. Ju mund ta zgjidhni këtë problem duke vendosur rrugën e duhur (në drejtorinë ekzistuese) për ruajtjen e sesioneve në skedarin php.ini dhe rinisjen e serverit.

Çdo skript që do të përdorë variabla (të dhëna) nga sesionet duhet të përmbajë rreshtin e mëposhtëm:

sesioni_fillimi ();

Kjo komandë i tregon serverit se kjo faqe ka nevojë për të gjitha variablat që lidhen me këtë përdorues (shfletues). Serveri i merr këto variabla nga skedari dhe i vë në dispozicion. Është shumë e rëndësishme të hapësh një sesion përpara se të dërgohen të dhëna tek përdoruesi; në praktikë, kjo do të thotë që është e dëshirueshme të thirret funksioni session_start () në fillim të faqes, si kjo:

sesioni_fillimi (); ?> ... Për të vendosur drejtorinë në të cilën do të ruhen skedarët e sesionit, përdorni funksionin session_save_path(): session_save_path($_SERVER["DOCUMENT_ROOT"]."/session"); sesioni_fillimi ();

Pasi të ketë filluar sesioni, mund të vendosen variablat globalë. Nëse i caktoni një vlerë çdo fushe të grupit $_SESSION, një ndryshore me të njëjtin emër regjistrohet automatikisht si një variabël sesioni. Ky grup është i disponueshëm në të gjitha faqet që përdorin sesionin. Le të marrim një program si shembull:

indeks.php Gjithçka në rregull. Sesioni u ngarkua! Le të shkojmë dhe të shohim se çfarë ka atje:

gjërat.php

Kur këta skedarë ekzekutohen në mënyrë sekuenciale, skripti i parë "index.php" do të prodhojë rezultatin e mëposhtëm:

Gjithçka në rregull. Sesioni u ngarkua! Le të shkojmë dhe të shohim se çfarë ka atje:

Dhe e dyta "dothings.php" është kjo:

Më kërkuan index.php

Ndryshorja $a është tani e disponueshme në të gjitha faqet në këtë sajt që kanë filluar seancat.

Funksione dhe truke të tjera të dobishme për të punuar me sesione:

  • unset ($_SESSION["a"])- sesioni "harron" vlerën e një ndryshoreje të caktuar të sesionit;
  • sesioni_shkatërrimi ()- sesioni është shkatërruar (për shembull, nëse përdoruesi u largua nga sistemi duke shtypur butonin "dalje");
  • sesioni_set_cookie_params(jeta int[, shtegu i vargut[, domeni i vargut]])- duke përdorur këtë funksion, mund të vendosni se sa do të "jetojë" seanca duke vendosur unix_timestamp, e cila përcakton kohën e "vdekjes" së seancës. Si parazgjedhje, një sesion jeton derisa klienti të mbyllë dritaren e shfletuesit.
  • sesioni_shkruaj_mbyll ()- regjistrimi i variablave të sesionit dhe mbyllja e tij. Kjo është e nevojshme për të hapur faqen në një dritare të re nëse faqja kërkon shumë kohë për t'u përpunuar dhe ka bllokuar skedarin e sesionit për shfletuesin tuaj.

Shembuj

Tani le t'i drejtohemi zbatimit praktik të mekanizmit të sesionit. Këtu do të shohim disa shembuj mjaft të thjeshtë por të dobishëm.

Autorizimi i përdoruesit

Pyetjet në lidhje me autorizimin e përdoruesit duke përdorur seancat PHP bëhen vazhdimisht në konferencat e programimit në internet. Mekanizmi për autorizimin e përdoruesve në sistem duke përdorur sesione është mjaft i mirë përsa i përket sigurisë (shih seksionin ).

Shembulli ynë do të përbëhet nga tre skedarë: index.php, autorize.php dhe secretplace.php. Skedari index.php përmban një formular ku përdoruesi do të fusë emrin e përdoruesit dhe fjalëkalimin e tij. Ky formular do t'i kalojë të dhënat skedarit autorize.php, i cili do t'i lejojë përdoruesit të hyjë në skedarin secretplace.php nëse autorizimi është i suksesshëm, përndryshe do të japë një mesazh gabimi.

Shembuj: indeks.php Shkruani fjalëkalimin

Identifikohu:
Fjalëkalimi:


autorizoj.php faqe... header("Vendndodhja: secretplace.php"); dalje; ) ) // nëse diçka shkoi keq, përdoruesi // do të marrë një mesazh gabimi. ?> Ke futur fjalëkalimin e gabuar!

vend i fshehtë.php Përshëndetje,ju jeni në faqen sekrete!!! :)

Siguria

Pra, ne mund të kalojmë një identifikues nga një faqe (skript PHP) në tjetrin (deri në thirrjen tjetër nga faqja jonë), që do të thotë se ne mund të dallojmë midis të gjithë vizitorëve të faqes. Meqenëse identifikuesi i sesionit është një numër shumë i madh (128 bit), praktikisht nuk ka asnjë shans që të jetë e mundur të merret me forcë brutale. Prandaj, sulmuesit i mbeten opsionet e mëposhtme:

  • ka një "trojan" në kompjuterin e përdoruesit që vjedh numrat e sesioneve;
  • sulmuesi kap trafikun midis kompjuterit të përdoruesit dhe serverit. Sigurisht, ekziston një protokoll i sigurt (i koduar) SSL, por jo të gjithë e përdorin atë;
  • një fqinj iu afrua kompjuterit të përdoruesit tonë dhe vodhi numrin e seancës.

Situata të tilla, bazuar në faktin se dikush i vjedh diçka dikujt, në përgjithësi, nuk janë në kompetencën e një programuesi. Për këtë duhet të kujdesen vetë administratorët dhe përdoruesit.

Megjithatë, PHP shumë shpesh mund të "mashtrohet". Le të shohim hakimet e mundshme në programin e autorizimit të përdoruesit:

  • Skedari autorize.php është një përpjekje për të gjetur një fjalëkalim duke përdorur një skript të palës së tretë;
  • Skedari secretplace.php është një përpjekje për të mashtruar programin duke futur vlerat e ndryshores $logged_user në shiritin e adresave të shfletuesit, si kjo:
    "http://www.yoursite.ru/secretplace.php? loged_user=haker"

Pra, në programin tonë, dy "vrima" duken qartë, njëra është e vogël dhe jo shumë e dukshme, por e dyta është thjesht e madhe, përmes së cilës shumica e hakerëve ngjiten atje ku nuk kanë nevojë.

Si të "patch" vrima numër 1?

Ne nuk do të shkruajmë tonelata kodesh për të bllokuar një adresë IP, etj., por thjesht kontrollojmë se nga vjen kërkesa, ose më saktë, nga cila faqe ka ardhur kërkesa, nëse është ndonjë faqe nga faqja jonë, atëherë gjithçka është në rregull, por në të gjitha rastet e tjera nuk do të lejojmë. Le të korrigjojmë skedarin autorize.php:

autorizoj.php V2 faqe... header("Vendndodhja: secretplace.php"); dalje; ) ) ) ?> Ke futur fjalëkalimin e gabuar!


Si të shpëtojmë nga "vrima" numër 2?

Supozoni se keni një faqe interneti ku çdo i vdekshëm mund të regjistrohet për të postuar në një forum. Natyrisht, në forum disa përdorues (administratorë, moderatorë) kanë më shumë mundësi se të tjerët, për shembull, ata mund të fshijnë mesazhe nga përdoruesit e tjerë. Ju ruani nivelin e aksesit të përdoruesit në seancë, në variablin $user_status, ku $user_status = 10 korrespondon me aksesin e plotë të sistemit. Mjafton që një sulmues që ka ardhur në sit të regjistrohet në mënyrë të rregullt, dhe më pas të shtojë në shiritin e adresave të shfletuesit ?user_status=10. Kështu që ju keni një administrator të ri në forum!

Në parim, çdo variabël skripti mund të vendoset përmes shiritit të adresave thjesht duke shtuar një pikëpyetje pas adresës së plotë në skript dhe emrin e ndryshores me vlerën e saj. Le të rregullojmë kodin tonë për të shmangur këtë:

vend i fshehtë.php V2 ndryshorja e pavendosur($_SESSION["logged_user"]); // hap sesionin sesion_start(); /* ju nuk mund të shkoni thjesht në këtë faqe... nëse emri i përdoruesit nuk është i regjistruar, atëherë ridrejtojeni atë në faqen index.php për të futur një hyrje dhe fjalëkalim... në fakt mund të bëni shumë gjëra këtu, për për shembull, mbani mend IP-në e përdoruesit dhe pas përpjekjes së tretë për të hyrë në skedarë, bllokoni atë. */ if(!isset($_SESSION["logged_user"]))( header("Vendndodhja: index.php"); dalje; ) ?> Përshëndetje,, ju jeni në një faqe sekrete!

Rezultatet

Mekanizmi i sesionit është një veçori mjaft e pastër e gjuhës PHP. Seancat janë të thjeshta, shumë fleksibël në përdorim. Meqë ra fjala, ekziston një veçori pak e dokumentuar e sesioneve PHP (e disponueshme duke filluar nga versioni 4.0.3) - seancat mund të ruajnë jo vetëm variabla, por edhe objekte.

Shembuj

?>
// Futja automatike e SID-ve në lidhje. ini_set("session.use_trans_sid", true); sesioni_fillimi (); ?> Kliko këtu!
Kliko këtu!!



// Një shembull i punës me sesione. sesioni_fillimi (); // Nëse faqja sapo është vizituar, rivendosni numëruesin. nëse (!isset($_SESSION["count"])) $_SESSION["count"] = 0; // Numëruesi i rritjes në seancë. $_SESSION["count"] = $_SESSION["count"] + 1; ?>

Kundër

kohë(et).
Mbyllni shfletuesin për të rivendosur numëruesin.
" target="_blank"> Hap një dritare të shfletuesit të fëmijëve.
// Një shembull i thjeshtë i përdorimit të seancave pa cookie. emri i sesionit ("test"); sesioni_fillimi (); $_SESSION["count"] = @$_SESSION["count"] + 1; ?>

Kundër

Në seancën aktuale të punës me shfletuesin, ju hapët këtë faqekohë(et).
Mbyllni shfletuesin për të rivendosur këtë numërues.
?">Kliko këtu për të rifreskuar faqen!

Përshëndetje i dashur komunitet.

Para së gjithash, dua t'ju falënderoj për një burim shumë të dobishëm. Më shumë se një herë kam gjetur këtu shumë ide interesante dhe këshilla praktike.

Qëllimi i këtij artikulli është të nxjerrë në pah kurthet e përdorimit të seancave në PHP. Sigurisht, ka dokumentacion PHP dhe shumë shembuj, dhe ky artikull nuk pretendon të jetë një udhëzues i plotë. Është krijuar për të zbuluar disa nga nuancat e punës me sesione dhe për të mbrojtur zhvilluesit nga humbja e kohës.

Rasti më i zakonshëm i përdorimit për seancat është, natyrisht, autorizimi i përdoruesit. Le të fillojmë me zbatimin më themelor në mënyrë që ta zhvillojmë në mënyrë të vazhdueshme ndërsa shfaqen detyra të reja.

(Për të kursyer hapësirë ​​dhe kohë, në shembujt do të kufizohemi në vetë funksionet e sesionit, në vend që të ndërtojmë një aplikacion testimi të plotë këtu me një hierarki të bukur klase, trajtim shterues të gabimeve dhe gjëra të tjera të drejta).

Funksioni startSession() ( // Nëse seanca ka filluar tashmë, ndaloni ekzekutimin dhe ktheni TRUE // (parametri session.auto_start në skedarin e cilësimeve php.ini duhet të fiket - vlera e paracaktuar) nëse (session_id()) kthe e vërtetë; përndryshe ktheje session_start(); // Shënim: Përpara versionit 5.3.0, session_start() u kthye TRUE edhe nëse ndodhi një gabim. // Nëse jeni duke përdorur një version nën 5.3.0, bëni një kontroll shtesë për session_id() // pas thirrjes sesion_start() ) funksion shkatërronSession() ( if (session_id()) ( // Nëse ka një seancë aktive, fshini kukit e sesionit, setcookie(sesion_name(), session_id(), time() -60*60*24); // dhe shkatërro sesionin session_unset(); session_destroy(); ) )

Shënim: Supozohet se lexuesi ka njohuri bazë për sesionet PHP, kështu që ne nuk do të mbulojmë këtu parimin e funksionimit të funksioneve session_start() dhe session_destroy(). Detyrat e paraqitjes së formularit të hyrjes dhe vërtetimi i përdoruesit nuk lidhen me temën e artikullit, kështu që ne gjithashtu do t'i heqim ato. Më lejoni t'ju kujtoj se për të identifikuar përdoruesin në çdo kërkesë pasuese, duhet të ruajmë identifikuesin e përdoruesit në variablin e sesionit (për shembull, me emrin userid) në momentin e hyrjes me sukses, i cili do të jetë i disponueshëm në të gjitha kërkesat pasuese. brenda jetëgjatësisë së seancës. Është gjithashtu e nevojshme të zbatohet përpunimi i rezultatit të funksionit tonë startSession(). Nëse funksioni u kthye FALSE - shfaqni formularin e hyrjes në shfletues. Nëse funksioni u kthye TRUE dhe ekziston një variabël sesioni që përmban ID-në e përdoruesit të vërtetuar (në rastin tonë, userid), shfaqni faqen e përdoruesit të vërtetuar (për më shumë mbi trajtimin e gabimeve, shihni shtimin e 2013-06-07 në seksionin mbi sesionin variablat).

Ndërkohë që gjithçka është e qartë. Pyetjet fillojnë kur kërkohet të zbatohet kontrolli i mungesës së aktivitetit të përdoruesit (koha e seancës), për të lejuar disa përdorues të punojnë njëkohësisht në një shfletues dhe gjithashtu për të mbrojtur seancat nga përdorimi i paautorizuar. Kjo do të diskutohet më poshtë.

Kontrolli i pasivitetit të përdoruesit me mjetet e integruara PHP

Pyetja e parë që shpesh lind midis zhvilluesve të të gjitha llojeve të konsolave ​​për përdoruesit është përfundimi automatik i seancës në rast të pasivitetit nga ana e përdoruesit. Nuk ka asgjë më të lehtë sesa ta bësh këtë me veçoritë e integruara të PHP. (Ky opsion nuk është shumë i besueshëm dhe fleksibël, por ne do ta konsiderojmë atë për hir të plotësisë).

Funksioni startSession() ( // Koha e paaktivitetit të përdoruesit (në sekonda) $sessionLifetime = 300; nëse (session_id()) kthehet e vërtetë; // Cakto jetëgjatësinë e kukive ini_set ("session.cookie_lifetime", $sessionLifetime); // Nëse përdoruesi është joaktiv caktohet koha e skadimit, caktoni jetëgjatësinë e sesionit në server // Shënim: Për një server prodhimi, rekomandohet të paracaktoni këto parametra në skedarin php.ini nëse ($sessionLifetime) ini_set("session.gc_maxlifetime", $sessionLifetime ); nëse (session_start( )) (setcookie(sesion_name(), session_id(), time()+$sessionLifetime); kthe e vërtetë; ) përndryshe kthej false; )

Disa shpjegime. Siç e dini, PHP përcakton se cilën sesion të fillojë bazuar në emrin e cookie-t të kaluar nga shfletuesi në kokën e kërkesës. Shfletuesi, nga ana tjetër, e merr këtë cookie nga serveri, ku vendoset nga funksioni session_start (). Nëse cookie në shfletues ka skaduar, ajo nuk do të kalojë në kërkesë, që do të thotë se PHP nuk do të jetë në gjendje të përcaktojë se cilin sesion të fillojë dhe ta trajtojë atë si krijimin e një sesioni të ri. Parametri i cilësimeve të PHP-së session.gc_maxlifetime, i cili është caktuar në kohëzgjatjen e mosaktivitetit të përdoruesit, cakton jetëgjatësinë e sesionit PHP dhe kontrollohet nga serveri. Kontrolli i jetëgjatësisë së sesionit funksionon si më poshtë (këtu shembulli i ruajtjes së sesionit në skedarë të përkohshëm konsiderohet si opsioni më i zakonshëm dhe i paracaktuar në PHP).

Kur krijohet një sesion i ri, një skedar me emrin sess_ krijohet në drejtorinë e vendosur si drejtoria e sesionit në parametrin e cilësimeve të PHP-së session.save_path. , Ku - identifikuesi i sesionit. Më tej, në çdo kërkesë, në momentin e fillimit të një sesioni tashmë ekzistues, PHP përditëson kohën e modifikimit të këtij skedari. Kështu, në çdo kërkesë të mëpasshme, PHP, nga diferenca midis kohës aktuale dhe kohës së fundit të modifikimit të skedarit të sesionit, mund të përcaktojë nëse sesioni është aktiv ose kohëzgjatja e tij tashmë ka skaduar. (Mekanizmi për heqjen e skedarëve të vjetër të sesionit diskutohet më në detaje në seksionin vijues.)

Shënim: Duhet të theksohet këtu se parametri session.gc_maxlifetime ndikon në të gjitha seancat brenda të njëjtit server (më saktë, brenda të njëjtit proces kryesor PHP). Në praktikë, kjo do të thotë që nëse disa sajte po funksionojnë në server dhe secila prej tyre ka afatin e vet të mosaktivitetit të përdoruesit, atëherë vendosja e këtij parametri në një nga faqet do të bëjë që ai të vendoset për sajte të tjera. E njëjta gjë vlen edhe për pritjen e përbashkët. Për të shmangur këtë situatë, drejtoritë e veçanta të sesioneve përdoren për çdo sajt brenda të njëjtit server. Vendosja e shtegut në direktorinë e sesionit bëhet duke përdorur parametrin session.save_path në skedarin e cilësimeve php.ini, ose duke thirrur funksionin ini_set(). Pas kësaj, sesionet e çdo sajti do të ruhen në drejtori të veçanta dhe parametri session.gc_maxlifetime i vendosur në një nga sajtet do të ndikojë vetëm në sesionin e tij. Ne nuk do ta shqyrtojmë këtë rast në detaje, veçanërisht pasi kemi një opsion më fleksibël për të kontrolluar pasivitetin e përdoruesit.

Kontrollimi i pasivitetit të përdoruesit me variablat e sesionit

Duket se versioni i mëparshëm, me gjithë thjeshtësinë e tij (vetëm disa rreshta shtesë kodi), jep gjithçka që na nevojitet. Por, çka nëse jo çdo kërkesë mund të konsiderohet si rezultat i aktivitetit të përdoruesit? Për shembull, faqja ka një kohëmatës që bën periodikisht një kërkesë AJAX për të marrë përditësime nga serveri. Një kërkesë e tillë nuk mund të konsiderohet si aktivitet i përdoruesit, që do të thotë se zgjatja automatike e jetëgjatësisë së sesionit nuk është e saktë në këtë rast. Por ne e dimë se PHP përditëson automatikisht kohën e modifikimit të skedarit të sesionit sa herë që thirret funksioni session_start(), që do të thotë se çdo kërkesë do të zgjasë jetëgjatësinë e sesionit dhe nuk do të ndodhë kurrë koha e mosveprimit të përdoruesit. Për më tepër, shënimi i fundit nga seksioni i mëparshëm mbi hollësitë e parametrit sesioni.gc_maxlifetime mund të duket shumë konfuz dhe i vështirë për t'u zbatuar nga dikush.

Për të zgjidhur këtë problem, ne do të braktisim përdorimin e mekanizmave të integruar PHP dhe do të prezantojmë disa variabla të reja të sesionit që do të na lejojnë të kontrollojmë vetë kohën e pasivitetit të përdoruesit.

Funksioni startSession($isUserActivity=true) ($sessionLifetime = 300; nëse (session_id()) kthehet i vërtetë; // Cakto jetëgjatësinë e kukive derisa shfletuesi të mbyllet (ne do të kontrollojmë gjithçka në anën e serverit) ini_set("sesion .cookie_lifetime", 0) ; nëse (! session_start()) kthen false; $t = time(); nëse ($sessionLifetime) ( // Nëse koha e mosveprimit të përdoruesit është caktuar, // kontrolloni kohën e kaluar që nga përdoruesi i fundit aktivitet // (koha e kërkesës së fundit kur u përditësua ndryshorja e sesionit të aktivitetit të fundit) nëse (isset($_SESSION["lastactivity"]) && $t-$_SESSION["lastactivity"] >= $sessionLifetime) ( // Nëse koha e kaluar që nga aktiviteti i fundit i përdoruesit është // më e madhe se koha e pasivitetit, atëherë seanca ka skaduar dhe ju duhet të përfundoni seancën shkatërroniSession(); ktheni false; ) tjetër ( // Nëse afati nuk ka ardhur ende , // dhe nëse kërkesa erdhi si rezultat i aktivitetit të përdoruesit, // përditësoni variablin e aktivitetit të fundit me vlerën e kohës aktuale, // duke e zgjatur kështu kohën e seancës me një seancë tjetër Lifetime sekonda nëse ($isUserActivity) $_SESSION["lastactivity "] = $t; ) ) kthimi i vërtetë; )

Le të përmbledhim. Në çdo kërkesë kontrollojmë nëse afati nuk është arritur që nga aktiviteti i fundit i përdoruesit deri në momentin aktual dhe nëse është, shkatërrojmë seancën dhe anulojmë funksionin, duke e kthyer FALSE. Nëse koha nuk është arritur dhe parametri $isUserActivity me vlerën TRUE i kalohet funksionit, ne përditësojmë kohën e aktivitetit të fundit të përdoruesit. Gjithçka që duhet të bëjmë është të përcaktojmë në skriptin e thirrjes nëse kërkesa është rezultat i një aktiviteti të përdoruesit dhe nëse jo, thirrni funksionin startSession me $isUserActivity të vendosur në FALSE.

Përditësim nga 07-06-2013
Trajtimi i rezultatit të funksionit sesionStart().

Komentet tërhoqën vëmendjen për faktin se kthimi FALSE nuk jep një kuptim të plotë të shkakut të gabimit, dhe kjo është absolutisht e drejtë. Unë nuk publikova trajtimin e detajuar të gabimeve këtu (vëllimi i artikullit tashmë nuk është i vogël), pasi kjo nuk lidhet drejtpërdrejt me temën e artikullit. Por duke pasur parasysh komentet, do ta sqaroj.

Siç mund ta shihni, funksioni sesionStart mund të kthejë FALSE në dy raste. Ose sesioni dështoi të fillonte për shkak të ndonjë gabimi të brendshëm të serverit (për shembull, cilësimet e gabuara të sesionit në php.ini), ose sesioni mbaroi. Në rastin e parë, duhet ta ridrejtojmë përdoruesin në një faqe gabimi që deklaron se ka probleme në server dhe një formular kontakti për mbështetjen. Në rastin e dytë, duhet ta transferojmë përdoruesin në formularin e hyrjes dhe të shfaqim një mesazh të përshtatshëm në të se koha e seancës ka skaduar. Për ta bërë këtë, ne duhet të fusim kodet e gabimit dhe të kthejmë kodin përkatës në vend të FALSE, dhe në metodën e thirrjes, ta kontrollojmë dhe të veprojmë në përputhje me rrethanat.

Tani, edhe nëse sesioni ekziston ende në server, ai do të shkatërrohet herën e parë kur aksesohet nëse afati i pasivitetit të përdoruesit ka skaduar. Dhe kjo do të ndodhë pavarësisht nga jeta e sesionit të caktuar në cilësimet globale të PHP.

Shënim:Çfarë ndodh nëse shfletuesi mbyllet dhe skedari i sesionit shkatërrohet automatikisht? Kërkesa për serverin herën tjetër që të hapet shfletuesi nuk do të përmbajë skedarin e sesionit dhe serveri nuk do të jetë në gjendje të hapë sesionin dhe të kontrollojë kohën e paaktivitetit të përdoruesit. Për ne, kjo është e barabartë me krijimin e një sesioni të ri dhe nuk ndikon në asnjë mënyrë funksionalitetin dhe sigurinë. Por lind një pyetje e drejtë - kush atëherë do ta shkatërrojë seancën e vjetër, nëse deri më tani e kemi shkatërruar pas skadimit të afatit? Apo do të mbetet përgjithmonë në drejtorinë e sesioneve? Për të pastruar seancat e vjetra, PHP ka një mekanizëm të quajtur grumbullimi i mbeturinave. Ai funksionon në kohën e kërkesës së radhës në server dhe pastron të gjitha seancat e vjetra bazuar në datën kur skedarët e sesionit janë modifikuar për herë të fundit. Por mekanizmi i mbledhjes së mbeturinave nuk aktivizohet me çdo kërkesë në server. Frekuenca (më saktë, probabiliteti) i nisjes përcaktohet nga dy parametrat e cilësimeve session.gc_probability dhe session.gc_divisor. Rezultati i ndarjes së parametrit të parë me të dytin është probabiliteti i aktivizimit të mekanizmit të grumbullimit të plehrave. Kështu, në mënyrë që mekanizmi i pastrimit të sesionit të lansohet në çdo kërkesë në server, këto parametra duhet të vendosen në vlera të barabarta, për shembull, "1". Kjo qasje siguron që drejtoria e sesionit të jetë e pastër, por është padyshim shumë e shtrenjtë për serverin. Prandaj, në sistemet e prodhimit, session.gc_divisor është vendosur si parazgjedhje në 1000, që do të thotë se mekanizmi i grumbullimit të mbeturinave do të funksionojë me një probabilitet prej 1/1000. Nëse eksperimentoni me këto cilësime në skedarin tuaj php.ini, mund të vëreni se në rastin e mësipërm, kur shfletuesi mbyllet dhe pastron të gjitha kukit e tij, ka ende seanca të vjetra të mbetura në drejtorinë e sesioneve për pak kohë. Por kjo nuk duhet t'ju shqetësojë, sepse. siç është përmendur tashmë, kjo në asnjë mënyrë nuk ndikon në sigurinë e mekanizmit tonë.

Përditësim nga 07-06-2013

Parandaloni varjen e skripteve për shkak të kyçjes së skedarit të sesionit

Në komente, u ngrit pyetja për varjen e ekzekutimit të njëkohshëm të skripteve për shkak të bllokimit të skedarit të sesionit (si opsioni më i mrekullueshëm - sondazh i gjatë).

Për të filluar, vërej se ky problem nuk varet drejtpërdrejt nga ngarkesa e serverit ose numri i përdoruesve. Sigurisht, sa më shumë kërkesa, aq më ngadalë ekzekutohen skriptet. Por kjo është një varësi indirekte. Problemi shfaqet vetëm brenda një sesioni, kur serveri merr disa kërkesa në emër të një përdoruesi (për shembull, njëra prej tyre është sondazh i gjatë, dhe pjesa tjetër janë kërkesa të zakonshme). Çdo kërkesë përpiqet të hyjë në të njëjtin skedar sesioni dhe nëse kërkesa e mëparshme nuk e zhbllokoi skedarin, atëherë tjetra do të mbetet në pritje.

Për të mbajtur në minimum bllokimin e skedarit të sesionit, rekomandohet shumë që të mbyllet sesioni duke thirrur funksionin session_write_close() menjëherë pasi të kenë përfunduar të gjitha manipulimet me variablat e sesionit. Në praktikë, kjo do të thotë që nuk duhet të ruani gjithçka në variablat e sesionit dhe t'u referoheni atyre gjatë ekzekutimit të skriptit. Dhe nëse keni nevojë të ruani disa të dhëna pune në variablat e sesionit, atëherë lexoni ato menjëherë në fillim të seancës, ruajini ato në variablat lokale për përdorim të mëvonshëm dhe mbyllni seancën (që do të thotë mbyllja e seancës duke përdorur funksionin session_write_close dhe jo shkatërrimi i tij duke përdorur session_destroy).

Në shembullin tonë, kjo do të thotë që menjëherë pas hapjes së sesionit, kontrollimit të jetëgjatësisë së tij dhe ekzistencës së një përdoruesi të autorizuar, ne duhet të lexojmë dhe ruajmë të gjitha variablat shtesë të sesionit të nevojshëm për aplikacionin (nëse ka), pastaj ta mbyllim seancën duke thirrur session_write_close( ) dhe vazhdoni të ekzekutoni një skenar, pavarësisht nëse është një sondazh i gjatë ose një kërkesë e rregullt.

Mbrojtja e seancës nga përdorimi i paautorizuar

Le të imagjinojmë një situatë. Një nga përdoruesit tuaj fikson një trojan që grabit skedarët e skedarëve të shfletuesit (në të cilin ruhet sesioni ynë) dhe e dërgon atë në emailin e specifikuar. Sulmuesi merr cookie-n dhe e përdor atë për të falsifikuar një kërkesë në emër të përdoruesit tonë të autorizuar. Serveri e merr dhe e përpunon me sukses këtë kërkesë sikur të ishte nga një përdorues i autorizuar. Nëse verifikimi shtesë i adresës IP nuk zbatohet, një sulm i tillë do të çojë në një hakim të suksesshëm të llogarisë së përdoruesit me të gjitha pasojat që pasojnë.

Pse u bë e mundur kjo? Natyrisht, për shkak se emri dhe identifikuesi i seancës janë gjithmonë të njëjta për të gjithë jetëgjatësinë e seancës, dhe nëse i merrni këto të dhëna, atëherë mund të dërgoni lirisht kërkesa në emër të një përdoruesi tjetër (natyrisht, brenda jetëgjatësisë së këtij sesioni) . Ky mund të mos jetë lloji më i zakonshëm i sulmit, por teorikisht duket mjaft i realizueshëm, veçanërisht duke marrë parasysh që një trojan i tillë nuk ka nevojë as për të drejtat e administratorit për të grabitur cookie-t e shfletuesit të një përdoruesi.

Si mund të mbroheni nga sulmet e këtij lloji? Përsëri, padyshim, duke kufizuar jetëgjatësinë e identifikuesit të sesionit dhe duke ndryshuar periodikisht identifikuesin brenda të njëjtit sesion. Ne gjithashtu mund të ndryshojmë emrin e sesionit, duke fshirë plotësisht të vjetrin dhe duke krijuar një sesion të ri, duke kopjuar të gjitha variablat e sesionit nga ai i vjetër në të. Por kjo nuk ndikon në thelbin e qasjes, prandaj, për thjeshtësi, ne kufizohemi vetëm në identifikuesin e sesionit.

Është e qartë se sa më e shkurtër jetëgjatësia e identifikuesit të sesionit, aq më pak kohë do të ketë një sulmues për të marrë dhe aplikuar cookie për të falsifikuar një kërkesë të përdoruesit. Idealisht, një identifikues i ri duhet të përdoret për çdo kërkesë, i cili do të minimizojë mundësinë e përdorimit të seancës së dikujt tjetër. Por ne do të shqyrtojmë rastin e përgjithshëm, kur koha e rifreskimit të ID-së së sesionit caktohet në mënyrë arbitrare.

(Le të heqim pjesën e kodit që tashmë është shqyrtuar).

Funksioni startSession($isUserActivity=true) ( ​​// Kohëzgjatja e ID-së së sesionit $idLifetime = 60; ... nëse ($idLifetime) ( // Nëse jetëgjatësia e ID-së së sesionit është caktuar, // kontrolloni kohën e kaluar që kur seanca ishte krijuar ose rigjenerimi i fundit // (koha e kërkesës së fundit kur u përditësua variabli i seancës) if (isset($_SESSION["starttime"])) ( if ($t-$_SESSION["starttime"] >= $idLifetime) ( / / Koha e seancës id ka skaduar // Gjeneroni një id të ri session_regenerate_id(true); $_SESSION["starttime"] = $t; ) ) other ( // Ne arrijmë këtu nëse sesioni sapo është krijuar // Vendosni gjenerimin e id-it të sesionit koha deri në orën aktuale $_SESSION["starttime"] = $t; ) ) kthehet e vërtetë; )

Pra, kur krijojmë një sesion të ri (që ndodh në momentin e një hyrjeje të suksesshme të përdoruesit), ne vendosim variablin e seancës starttime, e cila ruan kohën e gjeneratës së fundit të identifikuesit të sesionit për ne, në një vlerë të barabartë me kohën aktuale. të serverit. Më tej, në çdo kërkesë, ne kontrollojmë nëse ka kaluar mjaft kohë (idLifetime) nga gjenerimi i fundit i identifikuesit dhe nëse ka kaluar, ne gjenerojmë një të ri. Kështu, nëse gjatë kohëzgjatjes së caktuar të identifikuesit, një sulmues që ka marrë një cookie të autorizuar të përdoruesit nuk ka kohë për ta përdorur atë, serveri do ta konsiderojë kërkesën e rreme si të paautorizuar dhe sulmuesi do të dërgohet në faqen e hyrjes.

Shënim: ID-ja e re e sesionit vendoset në cookie-n e shfletuesit kur thirret session_regenerate_id(), e cila dërgon një cookie të re, të ngjashme me funksionin session_start(), kështu që ne nuk kemi nevojë ta përditësojmë vetë cookie-n.

Nëse duam të sigurojmë sa më shumë sesionet tona, mjafton të vendosim jetëgjatësinë e identifikuesit në një, ose madje të heqim funksionin session_regenerate_id () nga kllapat dhe të heqim të gjitha kontrollet, të cilat do të çojnë në rigjenerimin e identifikues në çdo kërkesë. (Unë nuk e kam testuar ndikimin e kësaj qasjeje në performancën dhe mund të them vetëm se funksioni session_regenerate_id(true) kryen në thelb vetëm 4 veprime: gjenerimi i një identifikuesi të ri, krijimi i një titulli me kukit e sesionit, fshirja e të vjetrës dhe krijimi një skedar të ri sesioni).

Digresioni lirik: Nëse trojani rezulton të jetë aq i zgjuar sa nuk do t'i dërgojë cookie një sulmuesi, por vetë organizon dërgimin e një kërkese të rreme të parapërgatitur menjëherë pas marrjes së një cookie, metoda e përshkruar më sipër ka shumë të ngjarë të mos jetë në gjendje të mbrojë kundër të tilla. një sulm, sepse ndërmjet kohës kur Trojani merr cookie-n dhe dërgon kërkesën e rreme, praktikisht nuk do të ketë asnjë ndryshim dhe ka të ngjarë që në këtë pikë ID-ja e sesionit të mos rigjenerohet.

Aftësia për të punuar njëkohësisht në një shfletues në emër të disa përdoruesve

Detyra e fundit që do të doja të merrja në konsideratë është mundësia e punës së njëkohshme në një shfletues nga disa përdorues. Kjo veçori është veçanërisht e dobishme gjatë fazës së testimit kur ju duhet të imitoni përdoruesit e njëkohshëm dhe është e dëshirueshme ta bëni këtë në shfletuesin tuaj të preferuar, në vend që të përdorni të gjithë arsenalin e disponueshëm ose të hapni shembuj të shumtë të shfletuesit në modalitetin e fshehtë.

Në shembujt tanë të mëparshëm, ne nuk e caktuam në mënyrë eksplicite emrin e sesionit, kështu që u përdor emri i paracaktuar PHP (PHPSESSID). Kjo do të thotë që të gjitha sesionet që kemi krijuar deri më tani kanë dërguar cookie në shfletuesin me emrin PHPSESSID. Natyrisht, nëse emri i cookie-t është gjithmonë i njëjtë, atëherë nuk ka asnjë mënyrë brenda të njëjtit shfletues për të organizuar dy sesione me të njëjtin emër. Por nëse do të përdornim emrin tonë të sesionit për secilin përdorues, atëherë problemi do të zgjidhej. Pra, le ta bëjmë atë.

Funksioni startSession($isUserActivity=true, $prefix=null) ( ... nëse (session_id()) kthehet true; // Nëse një prefiks përdoruesi kalon në parametrat, // vendosni një emër unik sesioni që përfshin këtë prefiks, // përndryshe vendosni një emër të përbashkët për të gjithë përdoruesit (për shembull, MYPROJECT) emri i sesionit ("MYPROJECT".($prefiks ? "_".$prefiks: "")); ini_set("session.cookie_lifetime", 0); nëse (! session_start()) kthen false; ...)

Tani e vetmja gjë që mbetet për të bërë është të siguroheni që skripti thirrës të kalojë një parashtesë unike për çdo përdorues në funksionin startSession(). Kjo mund të bëhet, për shembull, duke kaluar një prefiks në parametrat GET/POST të çdo kërkese, ose përmes një cookie shtesë.

konkluzioni

Si përfundim, do të jap kodin përfundimtar të plotë të funksioneve tona për të punuar me sesionet PHP, duke përfshirë të gjitha detyrat e diskutuara më sipër.

Funksioni startSession($isUserActivity=true, $prefiks=null) ( $sessionLifetime = 300; $idLifetime = 60; nëse (session_id()) kthehet i vërtetë; emri i sesionit ("MYPROJECT".($prefiksi ? "_".$prefiksi: "")); ini_set ("session.cookie_lifetime", 0); nëse (! session_start()) kthen false; $t = time(); if ($sessionLifetime) ( if (isset($_SESSION["lastactivity"] ) && $t-$_SESSION["lastactivity"] >= $sessionLifetime) (structSession(); kthe false; ) tjetër (nëse ($isUserActivity) $_SESSION["lastactivity"] = $t; ) ) nëse ($idLifetime ) ( if (isset($_SESSION["starttime"])) ( if ($t-$_SESSION["starttime"] >= $idLifetime) ( session_regenerate_id(true); $_SESSION["starttime"] = $t; ) ) else ( $_SESSION["starttime"] = $t; ) ) kthen true; ) funksioni deathSession() ( if (session_id()) ( session_unset(); setcookie(sesion_name(), session_id(), time() -60*60*24); session_destroy(); ) )

Shpresoj se ky artikull do të kursejë pak kohë për ata që kurrë nuk janë thelluar vërtet në mekanizmin e seancave dhe do të japë një kuptim të mjaftueshëm të këtij mekanizmi për ata që sapo kanë filluar të njihen me PHP.

Krijimi i sesionit

Gjëja e parë që duhet bërë për të punuar me sesionet (nëse ato janë tashmë të konfiguruara nga administratori i serverit) është të filloni mekanizmin e sesionit. Nëse ndryshorja session.auto_start është vendosur në "0" në cilësimet e serverit (nëse session.auto_start=1, atëherë seancat fillojnë automatikisht), atëherë çdo skript që duhet të përdorë të dhënat e sesionit duhet të fillojë me komandën

sesioni_fillimi ();

Me marrjen e një komande të tillë, serveri krijon një sesion të ri ose rikthen atë aktual, bazuar në ID-në e sesionit të kaluar në kërkesë. Si është bërë? Përkthyesi PHP kërkon një variabël që ruan ID-në e sesionit (si parazgjedhje, kjo është PHPSESSID) së pari në cookie, pastaj në variablat e kaluar duke përdorur kërkesat POST dhe GET. Nëse identifikuesi gjendet, atëherë përdoruesi konsiderohet i identifikuar, të gjitha URL-të zëvendësohen dhe kukit vendosen. Përndryshe, përdoruesi konsiderohet i ri, krijohet një identifikues i ri unik për të, më pas zëvendësohet URL-ja dhe vendosen cookies.

Komanda session_start() duhet të thirret në të gjitha skriptet në të cilat do të përdoren variablat e sesionit dhe përpara se ndonjë e dhënë të dalë në shfletues. Kjo për faktin se cookie-t vendosen vetëm përpara se informacioni të shfaqet në ekran.

Ju mund të merrni ID-në e sesionit aktual duke përdorur funksionin session_id().

Për qartësi, sesionit mund t'i jepet një emër duke përdorur funksionin sesion_name([sesion_name]).

Kjo duhet të bëhet përpara fillimit të seancës. Ju mund të merrni emrin e sesionit aktual duke përdorur të njëjtin funksion, të thirrur pa parametra: emri_sesionit();

Shembull. Krijimi i sesionit

Le të riemërtojmë skedarin tonë index.html në mënyrë që skriptet php të përpunohen, për shembull, në Index.php, të krijojmë një sesion dhe të shohim se çfarë identifikuesi dhe emri do të marrë.

sesioni_fillimi ();
// krijoni një sesion të ri ose
// rivendosni echo session_id ();
?>

Faqja ime kryesore
... // faqja kryesore

echo sesioni_emri ();
// shfaq emrin e sesionit aktual.
// Në këtë rast është PHPSESSID
?>

Nëse bëni të njëjtën gjë me skedarin autorize.php, atëherë vlerat e variablave të shfaqur (id-ja dhe emri i sesionit) do të jenë të njëjta nëse shkoni tek ai nga index.php dhe nuk e mbyllni dritaren e shfletuesit para kësaj ( atëherë ID e sesionit do të ndryshojë).

Regjistrimi i variablave të sesionit

Sidoqoftë, vetë identifikuesi dhe emri i sesionit janë pak të dobishëm për ne për zgjidhjen e problemeve tona. Ne duam të transferojmë dhe ruajmë variablat tona (për shembull, hyrjen dhe fjalëkalimin) gjatë seancës.

Për ta arritur këtë, ju vetëm duhet të regjistroni variablat tuaja:

regjistrimi_sesionit(emri_ndryshores1,
emri_ndryshore2, ...);

Vini re se nuk janë vlerat ato që regjistrohen, por emrat e variablave. Mjafton të regjistroni një variabël një herë në çdo faqe ku përdoren sesionet. Emrat e variablave i kalohen funksionit session_register() pa shenjën $.

Të gjitha variablat e regjistruar në këtë mënyrë bëhen globale (d.m.th., të aksesueshme nga çdo faqe) gjatë këtij sesioni të punës me sitin.

Ju gjithashtu mund të regjistroni një variabël thjesht duke shkruar vlerën e saj në grupin asociativ $_SESSION, d.m.th. duke shkruar

$_SESSION["emri_ndryshore"] =
"Vlera_ndryshore";

Ky grup ruan të gjitha variablat e sesioneve të regjistruara (d.m.th. globale).

Këto variabla aksesohen duke përdorur grupin $_SESSION["emri_variable"] (ose $HTTP_SESSION_VARS["emri_variable"] për PHP 4.0.6 dhe më të hershme).

Nëse opsioni register_globals është i aktivizuar në cilësimet e php, atëherë variablat e sesionit mund të aksesohen edhe si variabla të zakonshëm, për shembull: $ variable_name.

Nëse register_globals=off (i çaktivizuar), atëherë nuk mund të përdorni session_register() për të regjistruar variablat e kaluar nga metodat POST ose GET, d.m.th. thjesht nuk funksionon. Në përgjithësi, nuk rekomandohet përdorimi i të dyja metodave të regjistrimit të variablave, $_SESSION dhe session_register() në të njëjtën kohë.

Shembulli 12.3. Regjistrimi i variablave
Le të regjistrojmë hyrjen dhe fjalëkalimin e futur nga përdoruesi në faqen e autorizimit.

sesioni_fillimi ();
// krijoni një sesion të ri ose
// rivendos rrymën nëse (!isset($_GET["shko"]))(
jehonë"


login:
Fjalëkalimi: emri=passwd>

";
) tjeter (
$_SESSION["login"]=$_GET["login"];
// regjistro login e variablit
$_SESSION["passwd"]=$_MERRNI["passwd"];
// regjistroni variablin passwd
// tani hyrja dhe fjalëkalimi janë globale
// variabla për këtë sesion
nëse ($_GET["login"]=="gropë" &&
$_GET["passwd"]=="123") (
Header("Vendndodhja: secret_info.php");
// ridrejto te faqja
// secret_info.php
)else echo "Hyrje e pavlefshme,
Provo përsëri
";
}
print_r($_SESION);
?>

Tani, pasi kemi arritur në faqen secret_info.php, dhe në të vërtetë në çdo faqe tjetër të faqes, ne do të jemi në gjendje të punojmë me hyrjen dhe fjalëkalimin e futur nga përdoruesi, të cilat do të ruhen në grupin $_SESSION. Kështu, nëse ndryshojmë kodin e faqes sekrete (vini re se e riemëruam në secret_info.php) si kjo:

sesioni_fillimi ();
// krijoni një sesion të ri ose
// nxjerr të gjitha variablat e sesionit
?>

Informacion sekret

Këtu dua të ndaj sekretet me mikun tim Petya.



Pastaj do të marrim sa vijon në shfletuesin në faqen sekrete:

Array ( => gropë => 123)
Këtu dua të ndaj sekretet me mikun tim Petya.

Si rezultat, ne marrim një listë të variablave të regjistruar në autorize.php dhe, në fakt, vetë faqen sekrete.

Çfarë na jep kjo? Le të themi se një haker dëshiron të lexojë sekretet e Vasya dhe Petya. Dhe ai disi zbuloi emrin e faqes (ose faqeve) sekrete.

Pastaj ai mund të përpiqet të fusë thjesht adresën e saj në linjën e shfletuesit, duke anashkaluar faqen e autorizimit (hyrja e fjalëkalimit). Për të shmangur një depërtim të tillë në sekretet tona, duhet të shtoni vetëm disa rreshta në kodin e faqeve sekrete:

sesioni_fillimi ();
// krijoni një sesion të ri ose
// rivendos print_r aktual ($_SESSION);
// nxjerr të gjitha variablat e sesionit sif (!($_SESSION["login"]=="gropë" &&
$_SESSION["passwd"]==123))
// kontrolloni për korrektësinë
// fjalëkalimi i hyrjes
Header("Vendndodhja: autorize.php");
// nëse ka gabim, atëherë ridrejto te
// faqe autorizimi
?>

Informacion sekret
... // ndodhet këtu
//informacion sekret :)

Heqja e variablave të sesionit

Përveç të qenit në gjendje të regjistroni variablat e sesionit (d.m.th. t'i bëni ato globale gjatë gjithë sesionit), është gjithashtu e dobishme të jeni në gjendje të fshini variabla të tillë dhe sesionin në tërësi.

Funksioni session_unregister(variable_name) heq një variabël globale nga sesioni aktual (dmth. e heq atë nga lista e variablave të regjistruar).

Nëse regjistrimi është bërë duke përdorur $_SESSION ($HTTP_SESSION_VARS për PHP 4.0.6 dhe më herët), atëherë përdoret konstrukti i gjuhës unset(). Nuk kthen asnjë vlerë, por thjesht shkatërron variablat e specifikuar.

Ku mund të jetë i dobishëm? Për shembull, për të shkatërruar të dhënat rreth vizitorit (në veçanti, hyrjen dhe fjalëkalimin) pasi ai të largohet nga faqja sekrete. Nëse identifikimi dhe fjalëkalimi i saktë ruhen dhe dritarja e shfletuesit nuk mbyllet pas vizitës së sajtit, atëherë çdo përdorues tjetër i këtij kompjuteri do të jetë në gjendje të lexojë informacionin konfidencial.

Shembulli 1. Shkatërrimi i variablave të sesionit

Shtoni një rresht në skedarin secret_info.php për të dalë në faqen kryesore:

// ... kodi php
?>

Informacion sekret
... // ndodhet këtu
// informacion sekret :)
Në kryesore

Në Index.php, ne do të shkatërrojmë hyrjen dhe fjalëkalimin e futur më herët:

sesioni_fillimi ();
session_unregister("passwd");
// shkatërroni setun e fjalëkalimit ($_SESSION["login"]);
// shkatërroj loginprint_r($_SESSION);
// shfaq variablat e sesionit global
?>

Faqja ime kryesore
... // faqja kryesore

Tani, për të hyrë në faqen sekrete, do t'ju duhet të futni përsëri hyrjen dhe fjalëkalimin tuaj.

Për të rivendosur të gjitha variablat e sesionit, mund të përdorni funksionin session_unset();

Ju mund të shkatërroni të gjithë sesionin aktual me komandën session_destroy();

Ai nuk rivendos variablat e sesionit global ose fshin kukit, por shkatërron të gjitha të dhënat e lidhura me sesionin aktual.

sesioni_fillimi (); // inicializoj seancën $test = "Ndryshorja e sesionit";
$_SESSION["test"]= $test;
// regjistro variablin $test.
// nëse register_globals=on,
// atëherë mund të përdorni
// sesion_regjistrim ("test");

print_r($_SESION);
// nxjerr të gjitha variablat globale
echo sesion_id();
// nxjerr ID-në e sesionit
jehonë"


";
sesioni_unset();
// shkatërrojë të gjitha globale
// variablat e sesionitsprint_r($_SESSION);
echo sesion_id();
jehonë"
";
sesion_shkatërrim(); // shkatërroj sesionin print_r($_SESSION);
echo sesion_id();
?>

Si rezultat i këtij skripti, do të shfaqen tre rreshta: në të parën - një grup me elementin testues dhe vlerën e tij, si dhe një identifikues sesioni, në të dytën - një grup bosh dhe identifikues sesioni, në të tretën - një grup bosh. Kështu, është e qartë se pas shkatërrimit të sesionit, identifikuesi i tij gjithashtu shkatërrohet dhe ne nuk mund të regjistrojmë më variabla ose të kryejmë asnjë veprim me seancën fare.

Seancat janë në fakt shumë të thjeshta. Thjesht duhet të kuptoni se për çfarë shërbejnë dhe si janë rregulluar. Le t'i përgjigjemi së pari pyetjes së parë.
Ju mund ta dini se serveri në internet nuk mban një lidhje të përhershme me klientin dhe çdo kërkesë trajtohet si e re, pa marrë parasysh ato të mëparshme.

Kjo do të thotë, nuk mund të gjurmoni as kërkesat nga i njëjti vizitor, as të ruani variabla për të midis pamjeve individuale të faqeve. Pikërisht për të zgjidhur këto dy probleme u shpikën seancat.
Në fakt, seancat, me pak fjalë, janë një mekanizëm që ju lejon të identifikoni në mënyrë unike një shfletues dhe krijon një skedar për këtë shfletues në serverin që ruan variablat e sesionit.

Unë nuk do të përshkruaj në detaje nevojën për një mekanizëm të tillë. Këto janë raste të tilla si një karrocë blerjesh në një dyqan në internet, autorizim, si dhe probleme jo krejt të parëndësishme, si mbrojtja e pjesëve ndërvepruese të faqes nga spam.

Në parim, është mjaft e lehtë të bësh analogun tënd të seancave, jo aq funksionale sa PHP-ja e integruar, por e ngjashme në thelb. Në cookies dhe bazën e të dhënave.

Kur kërkojmë një skript, ne shikojmë nëse ka mbërritur një cookie me një emër specifik. Nëse nuk ka cookie, atëherë ne e vendosim atë dhe shkruajmë një linjë të re me të dhënat e përdoruesit në bazën e të dhënave. Nëse ka cookie, atëherë lexojmë nga baza e të dhënave. Me një kërkesë tjetër, fshijmë të dhënat e vjetra nga baza e të dhënave dhe tani kemi gati mekanizmin e sesionit. Mjaft e lehtë. Por ka disa nuanca që e bëjnë të preferueshme përdorimin e mekanizmit të integruar të sesionit.

Së pari ju duhet të identifikoni disi shfletuesin. Për ta bërë këtë, duhet t'i jepni atij një identifikues unik dhe t'i kërkoni që ta transferojë atë me çdo kërkesë. Më vjen turp ta pranoj, por kur mësova për herë të parë për seancat, mendova se ishte një mekanizëm i veçantë, një mënyrë e re që shfletuesi të komunikonte me serverin - "sesionet". Që ID-ja e seancës kalohet në një mënyrë të veçantë. Por zhgënjimi ishte i rëndë...

Sesionet përdorin mënyra standarde, të njohura për transferimin e të dhënave. Në fakt, thjesht nuk ka të tjerë.
Një identifikues është një ndryshore normale. Emri i tij i paracaktuar është PHPSESSID.
Detyra e PHP është ta dërgojë atë në shfletues në mënyrë që ta kthejë atë me kërkesën tjetër. Nga seksioni FAQ i përmendur tashmë, është e qartë se ndryshorja mund të kalohet vetëm në dy mënyra: në cookies ose në një kërkesë POST/GET.
PHP përdor të dyja opsionet.

Dy cilësime në php.ini janë përgjegjëse për këtë:

session.use_cookies - nëse është e barabartë me 1, atëherë PHP ia kalon identifikuesin cookies, nëse 0 - atëherë jo.
session.use_trans_sid nëse është e barabartë me 1, atëherë PHP e kalon atë duke e shtuar në URL dhe formon, nëse 0 - atëherë jo.

Ju mund t'i ndryshoni këto dhe parametra të tjerë të sesionit në të njëjtën mënyrë si cilësimet e tjera të PHP - në skedarin php.ini, si dhe duke përdorur komandën ini_set () ose në skedarët e konfigurimit të serverit në internet

Nëse aktivizohet vetëm i pari, atëherë në fillim të seancës (me çdo telefonatë sesioni_fillimi ()) kukit vendosen te klienti. Shfletuesi e kthen saktë këtë cookie në çdo kërkesë tjetër dhe PHP ka një ID të sesionit. Problemet fillojnë nëse shfletuesi nuk kthen cookie-t. Në këtë rast, pa marrë cookie me një identifikues, PHP do të fillojë një sesion të ri gjatë gjithë kohës dhe mekanizmi nuk do të funksionojë.

Nëse aktivizohet vetëm i dyti, atëherë nuk vendosen cookie. Dhe ajo që ndodh është për hir të së cilës, në thelb, në fakt, ia vlen të përdorni mekanizmin e integruar të sesionit. Pasi skripti të kryejë punën e tij dhe faqja të jetë formuar plotësisht, PHP skanon të gjitha dhe shton në secilën lidhje dhe në secilën formë transferimin e identifikuesit të sesionit. Duket diçka si kjo:

Indeksi

shndërrohet në

Indeksi

Shtimi i një fushe të fshehur në forma

Teorikisht, në seancat tona të bëra vetë me ju për skedarët e skedarëve dhe bazën e të dhënave, ju mund t'i atribuoni manualisht transferimin e ID-së në të gjitha lidhjet - dhe më pas sesionet tona do të funksionojnë pavarësisht nga skedarët e skedarëve të skedarëve. Por, e shihni, a është më e këndshme kur dikush tjetër e bën këtë punë? ;-)

Të dy opsionet janë aktivizuar si parazgjedhje në versionet e fundit të PHP. Si sillet PHP në këtë rast? Cookie është gjithmonë e vendosur. Dhe lidhjet plotësohen automatikisht vetëm nëse PHP nuk gjen cookie me ID-në e sesionit. Kur një përdorues viziton sajtin për herë të parë në këtë sesion, kukit vendosen dhe lidhjet plotësohen. Në kërkesën tjetër, nëse kukit mbështeten, PHP i sheh kukit dhe ndalon plotësimin e lidhjeve. Nëse cookies nuk funksionojnë, atëherë PHP vazhdon të shtojë id-në në lidhje siç duhet dhe sesioni nuk humbet.
Përdoruesit që kanë të aktivizuar cookie-t do ta shohin lidhjen e gjatë me ID-në vetëm një herë.

Përfundoi me transferimin e identifikuesit. Tani mbetet për të lidhur një skedar me të dhëna në anën e serverit. PHP do ta bëjë atë për ne. Është mjaft e lehtë të shkruash:

sesioni_fillimi ();
$_SESSION [ "test" ]= "Përshëndetje botë!" ;

Dhe PHP do të shkruajë në skedarin e lidhur me këtë sesion testin e variablës.

Këtu ka një shënim shumë të rëndësishëm.

varg $_SESSION- e veçantë.
Në të, në fakt, ka variabla që duam t'i vëmë në dispozicion në skripta të ndryshëm.
Për të vendosur një variabël në një sesion, mjafton ta caktoni atë në një element të grupit $_SESSION.
Për të marrë vlerën e tij - thjesht referojuni të njëjtit element. Një shembull do të jetë më poshtë.

Mbledhja e mbeturinave - heqja e skedarëve të vjetëruar PHP gjithashtu trajtohet vetë. Si dhe kodimi i të dhënave dhe një mori gjërash të tjera të nevojshme. Si rezultat i këtij kujdesi, puna me seancat është shumë e thjeshtë.
Këtu, në fakt, erdhëm te shembulli i punës së seancave.
Shembulli është shumë i vogël:

sesioni_fillimi ();

jehonë "Ju e keni përditësuar këtë faqe". $_SESSION[ "counter" ]++. "një herë.";
jehonë"
përditësimi";
?>

Kontrollojmë nëse kemi një variabël numërues në seancë, nëse jo, atëherë e krijojmë atë me vlerën 0 dhe më pas shfaqim vlerën e tij dhe e rrisim me një. Vlera e rritur do të shkruhet në sesion dhe herën tjetër që do të thirret skripti, ndryshorja do të ketë vlerën 1, e kështu me radhë. Gjithçka është shumë e thjeshtë.

Për të pasur akses në variablat e sesionit në çdo faqe të faqes, duhet të shkruani VETËM NJË (!) rresht në fillim të ÇDO skedari në të cilin na duhen sesione:

sesioni_fillimi ();

sesioni_fillimi ();
nëse ($_SESSION[ "i autorizuar" ]<> 1 ) {
header ("Vendndodhja: /auth.php");
dalje;
}

Heqja e variablave nga sesioni. Nëse keni register_globals=off, atëherë mjafton të shkruani

unset($_SESSION[ "var" ]);

Nëse jo, atëherë afër me të duhet të shkruani:

session_unregister("var");

Është shumë e rëndësishme të kuptojmë se për çfarë sesionesh duhen përdorur dhe për çfarë jo.

Së pari, mbani mend se seancat mund të përdoren vetëm kur përdoruesi ka nevojë për to, dhe jo për ta penguar atë. Në fund të fundit, ai mund të heqë qafe identifikuesin në çdo kohë!
Le të themi, kur kontrolloni që një person po plotëson formularin, dhe jo një skript, vetë përdoruesi është i interesuar që sesioni të funksionojë - përndryshe ai nuk do të jetë në gjendje të dorëzojë formularin! Por për të kufizuar numrin e kërkesave në skript, seanca nuk është më e përshtatshme - një skript me qëllim të keq thjesht nuk do të kthejë një identifikues.

Së dyti. Është e rëndësishme të kuptohet qartë fakti që një seancë është një seancë pune me një faqe, siç e kupton një person. Erdhi, punoi, mbylli shfletuesin - seanca mbaroi. Si një seancë filmi. Nëse dëshironi të shihni një tjetër, blini një biletë të re. Filloni një seancë të re. Ekziston edhe një shpjegim teknik për këtë. Mekanizmi i sesionit garantohet të funksionojë vetëm derisa shfletuesi të mbyllet. Në fund të fundit, cookies mund të mos funksionojnë për klientin, dhe në këtë rast, natyrisht, të gjitha lidhjet e plotësuara me një identifikues do të zhduken kur të mbyllet.

Vërtetë, seanca mund të zhduket pa mbyllur shfletuesin. Për shkak të kufizimeve të diskutuara në këtë artikull, mekanizmi i sesionit nuk mund të përcaktojë kur përdoruesi ka mbyllur shfletuesin. Për këtë, përdoret një kohëzgjatje - një kohë e paracaktuar pas së cilës ne konsiderojmë se përdoruesi është larguar nga faqja. Si parazgjedhje, ky cilësim është 24 minuta.

Nëse dëshironi të ruani informacionin e përdoruesit për një periudhë më të gjatë, atëherë përdorni cookies dhe, nëse është e nevojshme, një bazë të dhënash në server. Në veçanti, kështu funksionojnë të gjitha sistemet e njohura të autorizimit:

Me identifikimin e përdoruesit, fillon seanca dhe në të transmetohet shenja e autorizimit.
- Nëse ju duhet të "kujtoni" përdoruesin, atëherë atij i vendosen cookie që e identifikojnë atë.
- Herën tjetër që përdoruesi të hyjë në faqe, për t'u identifikuar, ose duhet të fusë një fjalëkalim, ose vetë sistemi do ta njohë atë nga cookie-t e vendosur më parë dhe seanca do të fillojë. seancë e re në vend që të vazhdohet e vjetra.

Së treti, nuk duhet të filloni seancat pa dallim, për këdo që hyn në faqe. Kjo do të krijojë një ngarkesë krejtësisht të panevojshme. Mos përdorni seanca për gjëra të vogla - për shembull, në sportele. Ajo që spylog i quan sesione, natyrisht, llogaritet bazuar në statistikat e goditjeve, dhe duke mos përdorur mekanizmin e sesionit të ngjashëm me PHP.

Përveç kësaj, le të marrim një motor kërkimi që indekson faqen tuaj. Nëse roboti i kërkimit nuk mbështet cookie, atëherë si parazgjedhje PHP do të furnizojë PHPSESSID në lidhje, të cilat mund të mos jenë shumë të njohura me motorin e kërkimit, i cili, sipas thashethemeve, nuk favorizon lidhjet dinamike gjithsesi, por këtu, në përgjithësi, me çdo vizitë - një adresë të re!

Nëse seancat përdoren për të kufizuar aksesin në një seksion privat të faqes, atëherë gjithçka është thjesht një motor kërkimi dhe nuk duhet ta indeksojë atë. Nëse duhet t'u tregoni të njëjtën faqe përdoruesve të autorizuar dhe të paautorizuar, atëherë ky truk do t'ju ndihmojë - filloni seancën vetëm për ata që kanë futur fjalëkalimin ose për ata që kanë filluar tashmë seancën.

Për ta bërë këtë, në krye të çdo faqeje në vend të vetëm sesioni_fillimi () ne shkruajmë:

nëse (isset($_REQUEST [emri_sesionit ()])) sesioni_fillimi ();

kështu, Ne e fillojmë seancën vetëm për ata që dërguan identifikuesin.
Prandaj, është e nevojshme t'i dërgoni përdoruesit për herë të parë - në kohën e autorizimit.

Nëse emri dhe prol janë të sakta, ne shkruajmë sesioni_fillimi () !

Gabimet më të zakonshme që PHP hedh kur përpiqet të punojë me sesionet janë:
Dy prej tyre

Paralajmërim: Nuk mund të dërgohet skedari i sesionit - titujt janë dërguar tashmë
Paralajmërim: Nuk mund të dërgohet kufizuesi i memories së sesionit - titujt janë dërguar tashmë

janë shkaktuar nga e njëjta arsye, zgjidhja përshkruhet në këtë false

Paralajmërim: open(/tmp\sess_SID, O_RDWR) dështoi: Nuk ka skedar ose direktori të tillë (2) në shtegun e plotë_script në numrin e linjës

para se ajo të dukej

Paralajmërim: Shkrimi i të dhënave të sesionit (skedarët) dështoi. Ju lutemi verifikoni që cilësimi aktual i session.save_path është i saktë (/tmp) ,

nëse përkthehet nga anglishtja, ai shpjegon problemin në detaje: shtegu për në drejtorinë e specifikuar në php.ini nuk është i disponueshëm, në të cilin janë shkruar skedarët e sesionit. Ky gabim është më i lehtë për t'u rregulluar. Thjesht shkruani një direktori që ekziston dhe është e shkruajtshme, për shembull,

sesioni.rruga_save = c:\windows\temp

Dhe mos harroni të rinisni Apache pas kësaj.

Siç rezulton, zgjuarsia njerëzore nuk ka kufij dhe prandaj jam i detyruar të shpjegoj:
mesazhi i tretë i gabimit (nuk mund të gjendet direktoria) do të rezultojë në mënyrë të pashmangshme në dy të parat, pasi mesazhi i gabimit del në shfletues dhe asnjë titull nuk mund të përdoret pas tij. Prandaj, mos nxitoni të kërkoni një përfundim të parakohshëm, por fillimisht shkruani rrugën e duhur!

Problemi tjetër më i zakonshëm me seancat është trashëgimia e rëndë e register_globals. MOS u jepni emra variablave të skriptit që përputhen me indekset e grupit $_SESSION!

Me register_globals=on, vlerat do të mbishkruajnë njëra-tjetrën dhe do të ngatërroheni.

Nëse nuk funksionon, por nuk shfaqen mesazhe, atëherë shtoni dy rreshta në fillim të skenarit që janë përgjegjës për shfaqjen e TË GJITHA gabimeve në ekran - është mjaft e mundur që të ketë gabime, por thjesht nuk i shihni ato .

ini_set("gabimet_afishimi" , 1 );
raportimi i gabimit (E_ALL);

ose shikoni gabimet në error_log. Në përgjithësi, tema e shfaqjes së mesazheve të gabimit është përtej qëllimit të këtij artikulli, kështu që vetëm sigurohuni që të paktën t'i shihni ato. Mund të lexoni pak më shumë rreth gjetjes së gabimeve në këtë seksion.

Nëse jeni të sigurt se nuk ka gabime, por shembulli i mësipërm nuk funksionon gjithsesi, atëherë është e mundur që PHP të mos mundësojë kalimin e ID-së përmes url-së, dhe cookies nuk funksionojnë për ndonjë arsye.
Shikoni se çfarë keni me cookies.

Në përgjithësi, nëse seancat nuk funksionojnë për ju, atëherë së pari përpiquni të kaloni me dorë identifikuesin e sesionit, domethënë, bëni një lidhje dhe caktoni një identifikues për të:

sesioni_fillimi ();
if (!isset($_SESSION [ "counter" ])) $_SESSION [ "counter" ]= 0 ;
jehonë "Ju e keni përditësuar këtë faqe". $_SESSION[ "counter" ]++. "një herë.

përditësimi";
?>

Kur e bëni këtë, sigurohuni që direktiva session.use_only_cookies të mos përfshihet, gjë që e pengon PHP-në të pranojë një ID të sesionit nëse është kaluar përmes një URL

Nëse ky shembull nuk funksionon, atëherë problemi është ose në atë banal gabime printimi(gjysma e "problemeve" me sesionet vijnë nga një emër variabli i shkruar gabimisht), ose në një version të PHP që është shumë i vjetër: mbështetja e sesioneve u prezantua në versionin 4.0 dhe një grup $_SESSION- në 4.1 (E përdorur më parë $HTTP_SESSION_VARS).

Nëse funksionon, atëherë problemi është në cookies. Gjurma - çfarë lloj cookie i vendos serveri në shfletues, nëse shfletuesi e kthen atë. Kërkimi është shumë i dobishëm duke parë shkëmbimin e titujve HTTP midis shfletuesit dhe serverit.

Një shpjegim se si funksionojnë cookies është përtej fushëveprimit të këtij teksti tashmë shumë të gjatë, por të paktën sigurohuni që serveri të dërgojë cookie me një identifikues dhe shfletuesi t'i kthejë ato. Dhe në të njëjtën kohë, identifikuesit përkojnë me njëri-tjetrin =)
Vendosja e kukive duhet të duket si kjo

Set-Cookie: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6;

Set-Cookie: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6; rrugë =/

(nëse po kërkoni një skript jo nga direktoria rrënjësore)
Përgjigja e serverit duhet të duket si kjo

Kuki: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6

Cookie: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6; b=b

nëse shfletuesi kthen skedarë të ndryshëm nga ID-ja e sesionit.

Nëse shembulli nga këtu funksionon, por kodi juaj nuk funksionon, atëherë problemi padyshim nuk është me seancat, por me algoritmin. Kërkoni se ku e keni humbur variablin, transferoni shembullin nga këtu hap pas hapi, korrigjoni skriptin tuaj.

Një problem tjetër mund të lindë nëse përdorni ridrejtimin e kokës ose navigimin JavaScript.
Fakti është se PHP automatikisht shton identifikuesin e sesionit vetëm në lidhjet e formularit
, por nuk e bën këtë për headers, javascript, meta etiketat.

Prandaj, duhet të shtoni identifikuesin me dorë, për shembull, si kjo:

header("Vendndodhja: /script.php?" .emri_sesionit(). "=" .sesion_id());

Gjithashtu, një shumë e rrallë, dhe është plotësisht e paqartë nga vjen, problemi është se cilësimi session.save_handler ka një vlerë të ndryshme nga skedarët. Nëse nuk është, rregullojeni.

  • Përveç cookies, mekanizmi i sesionit dërgon gjithashtu tituj që ndalojnë ruajtjen e faqeve (i njëjti kufizues i cache-it). Për html, kjo është e saktë dhe e nevojshme. Por kur përpiqeni të dërgoni një skedar me një skript që kontrollon autorizimin, Internet Explorer refuzon ta shkarkojë atë. Kjo është për shkak të këtij titulli. Thirrni
    session_cache_limiter ("privat");
    para fillimit të seancës duhet të zgjidhë problemin.
  • Sado e çuditshme të duket, por në grup $_SESSION ju nuk mund të përdorni indekse numerike - $_SESSION [ 1 ], $_SESSION [ "10" ]- seancat nuk do të funksionojnë.
  • Diku midis versioneve 4.2 dhe 5.0 nuk ishte e mundur të vendosej session.use_trans_sid me ini_set (). Duke filluar nga 5.0 tashmë është e mundur përsëri.
  • Përpara versionit 4.3.3 të kukive, PHP dërgonte skedarë vetëm nëse kërkesa nuk përfshinte një identifikues kur filloi sesioni. Tani cookies dërgohen në çdo telefonatë fillimi i sesionit

    Nëse keni më shumë pyetje ose diçka nuk është e qartë - mirë se vini në faqen tonë



Top