Računala Windows Internet

Sesije. Detaljan opis rada i objašnjenje mehanizma. Zaštita ID -a sesije u PHP organizaciji inurl knjiga gostiju php phpsessid

Sesije u PHP -u ​​ili kako se spremaju podaci o korisniku ili korisniku koji je ušao na web mjesto pri navigaciji između stranica web stranice bez većih poteškoća. Pouka je jako važna. Relevantno za stvaranje 95% web stranica.

Što je sesija u php -u

Sesije se koriste za spremanje privremenih podataka (na primjer, da je korisnik ušao na web mjesto) prilikom navigacije između stranica istog web mjesta. Prilikom korištenja sesija podaci se spremaju u privremene datoteke na poslužitelju.
Najčešće se sesije (međutim, i kolačići) koriste pri stvaranju internetskih trgovina, foruma, oglasnih ploča, društvenih mreža, blogova i drugih resursa. Pogodnost sustava sesije je pohranjivanje privremenih podataka prijavljenog korisnika / korisnika, čiji su podaci u brzom pristupu određeno vrijeme. Sesija ima prirodni datum isteka - sve dok se preglednik ne zatvori. Ako zatvorite samo stranicu, tada kada otvorite web stranicu, podaci o korisniku / kupcu i dalje će biti dostupni.

Logika sesije

Sesija (ili sesija) je vrsta privremene pohrane podataka. Odmah vas upozoravam da je vrijedno spremiti malu količinu podataka. Na primjer, prijava i lozinka korisnika za prijavu ili njegov serijski broj u bazi podataka.

Primjer rada
1. Korisnik unosi korisničko ime i lozinku te ulazi na web mjesto
2. Podaci s prijavom i lozinkom spremaju se u sesiju jedne od stranica web stranice:

Datoteka index.php

Session_start (); // svaka datoteka u kojoj želite koristiti podatke sesije mora sadržavati naredbu "start session" na početku koda

$ login = "admin";
$ password = "proći";
$ _SESSION ["login"] = $ prijava; // spremanje varijable koja sadrži prijavu
$ _SESSION ["lozinka"] = $ lozinka; // spremanje varijable koja sadrži lozinku

3. Kada prijeđete na drugu stranicu web stranice, bit će dostupni i ovi podaci:

Datoteka primjer.php(ili bilo koju drugu stranicu)

Ponovite odjeljak "Vaša prijava". $ _ SESSION ["prijava"]; // prikazat će se "Vaša prijava je administrator", iako nismo zabilježili podatke na ovoj stranici!
Vidite, jednostavno je!

4. Ako želite izbrisati podatke o sesiji, dovoljno je:

Datoteka primjer.php

Session_start (); // ponovno "pokretanje sesije"

Poništeno ($ _ SESSION ["login"]); // ovako je varijabla neregistrirana ili "uništena"
echo "Vaša prijava". $ _ SESSION ["login"]; // prikazat će se "Vaša prijava". Budući da smo ga uništili u zadnjem retku, nema ni podataka.

Session_destroy (); // uništiti sesiju. Nestali su svi podaci, uključujući $ _SESSION ["lozinku"]. Kada se to zatraži, prikazat će se pogreška
Općenito, takav prijenos sličan je POST metodi, ali više ne morate pisati puno nepotrebnog koda, a svi podaci preneseni sa stranice na stranicu pohranjuju se u privremene datoteke na poslužitelju. Opet, sesije bi trebale sadržavati male količine podataka, tako da su prikladne za spremanje korisničkog imena / lozinke, košarice za kupnju i drugih malih količina.

Prosljeđivanje vrijednosti ili niza pomoću PHP sesije

U sesiji možete upisati ne samo niz, već i niz podataka. Samo nemojte pretjerivati ​​s veličinom niza, jer će sve to utjecati na performanse i zauzeti prostor na poslužitelju.

Ponovno koristimo određenu početnu stranicu index.php

Session_start ();

$ r = niz ("jedan", "dva", "tri");

$ _SESSION ["arr"] = $ r;

Na stranicu na kojoj će se sve prikazati
Spremili smo podatke u sesiju i slijedimo vezu do druge stranice, gdje ćemo prikazati sve podatke.

Primatelj datoteke, stranica test.php gdje otvaramo niz

Session_start ();
print_r ($ _ SESSION ["arr"]);
// ispisat će se
/*
Niz
=> jedan
=> dva
=> tri
*/
?>
Možda biste htjeli dovršiti lekciju o tome. Općenito, sve bi trebalo biti jasno.

Ostale funkcije za rad sa sesijama

session_unregister (niz)- sesija zaboravlja vrijednost navedene globalne varijable;
session_destroy ()- sesija je uništena (na primjer, ako je korisnik napustio sustav pritiskom na gumb za odjavu);
parametri_skup_kod_kuše_sesije (int životni vijek [, niz niza [, nizova domena]])- pomoću ove funkcije možete postaviti koliko će sesija trajati postavljanjem unix_timestamp koji određuje vrijeme smrti sesije.

Popis funkcija za rad sa sesijama (session) u php -u
session_cache_expire - Vraća istek trenutne predmemorije
session_cache_limiter - Dohvatite i / ili postavite trenutno ograničenje predmemorije
session_commit - alias za session_write_close ()
code_decode - Dekodira podatke sesije iz niza
session_destroy - Uništava sve podatke registrirane za sesiju
session_encode - šifrira trenutne podatke sesije kao niz
session_get_cookie_params - Dohvatite parametre kolačića sesije
session_id - dobiva i / ili postavlja trenutni id sesije
session_is_registered - određuje je li varijabla registrirana u sesiji
session_module_name - dobiva i / ili instalira modul trenutne sesije
session_name - dobiva i / ili postavlja naziv trenutne sesije
session_regenerate_id - Mijenja trenutni ID sesije s novo generiranim
session_register - registrira jednu ili više varijabli za trenutnu sesiju
session_save_path - dobiva i / ili postavlja put za spremanje trenutne sesije
session_set_cookie_params - postavlja parametre kolačića sesije
session_set_save_handler - postavlja funkcije pohrane sesija na razini korisnika
session_start - inicijalizira podatke sesije
session_unregister - Poništite registraciju varijable iz trenutne sesije
session_unset - Oslobađa sve varijable sesije
session_write_close - Zapisuje podatke o sesiji i kraj sesije

Primjeri sjednica

Brojač pregleda stranica tijekom sesije. Ilustrativan primjer rada. Međutim, nakon zatvaranja preglednika odbrojavanje će početi iznova.

Brojač posjeta jednoj stranici u jednoj sesiji

// Jednostavan primjer korištenja sesija bez kolačića.
session_name ("test");
session_start ();
$ _SESSION ["count"] = @ $ _ SESSION ["count"] + 1;
?>

Brojač


U trenutnoj sesiji s preglednikom otvorili ste ovu stranicu
vrijeme (a).
Zatvorite svoj preglednik da biste poništili ovaj brojač.
Kliknite ovdje za osvježavanje stranice!
Svakim prijelazom brojač će se povećavati za 1)

Hvala na pažnji! Sretno u vašim nastojanjima!

Sesije su zapravo vrlo jednostavne. Samo trebate razumjeti čemu služe i kako su raspoređeni. Odgovorimo prvo na prvo pitanje.
Možda znate da web poslužitelj ne održava stalnu vezu s klijentom, pa se svaki zahtjev obrađuje kao novi, bez komunikacije s prethodnim.

To jest, ne možete pratiti zahtjeve istog posjetitelja niti mu spremati varijable između prikaza zasebnih stranica. Sesije su izmišljene za rješavanje ova dva problema.
Zapravo, sesije, ako su ukratko, mehanizam koji vam omogućuje jedinstvenu identifikaciju preglednika i stvara datoteku za ovaj preglednik na poslužitelju koja pohranjuje varijable sesije.

Neću detaljno opisivati ​​potrebu za takvim mehanizmom. To su slučajevi poput košarice za kupnju u internetskoj trgovini, autorizacije, kao i ne sasvim trivijalni problemi, poput, primjerice, zaštite interaktivnih dijelova web mjesta od neželjene pošte.

U načelu, prilično je lako napraviti vlastiti analogni sesije, ne tako funkcionalan kao ugrađeni PHP, ali u biti sličan. O kolačićima i bazi podataka.

Kada tražimo skriptu, provjeravamo je li kolačić došao s određenim imenom. Ako nema kolačića, postavite ih i u bazu upišite novi redak s korisničkim podacima. Ako postoje kolačići, onda čitamo iz baze podataka. S još jednim zahtjevom brišemo stare zapise iz baze podataka i sada imamo spreman mehanizam sesije. Uopće nije teško. No, postoje neke nijanse zbog kojih je poželjnije koristiti ugrađeni mehanizam sesije.

Prvo morate nekako identificirati preglednik. Da biste to učinili, morate mu dati jedinstveni identifikator i zamoliti ga da ga prenese sa svakim zahtjevom. Sram me je priznati, ali kad sam tek saznao za sesije, pomislio sam da je to nekakav poseban mehanizam, neki novi način komunikacije između preglednika i poslužitelja - "sesije". Da je identifikator sesije proslijeđen na neki poseban način. No, razočaranje je bilo okrutno ...

Sesije koriste standardne, dobro poznate metode prijenosa podataka. Zapravo, drugih jednostavno nema.
Identifikator je regularna varijabla. Prema zadanim postavkama, njegovo ime je PHPSESSID.
Zadatak PHP -a je poslati ga pregledniku kako bi ga vratio sa sljedećim zahtjevom. Iz već spomenutog odjeljka FAQ jasno je da se varijabla može proslijediti samo na dva načina: u kolačićima ili putem POST / GET zahtjeva.
PHP koristi obje opcije.

Za to su odgovorne dvije postavke u php.ini:

session.use_cookies - ako je jednako 1, tada PHP prosljeđuje identifikator kolačićima, ako 0 - tada ne.
session.use_trans_sid ako je jednako 1, tada ga PHP prosljeđuje dodavanjem URL -a i obrazaca, ako je 0 - onda ne.

Ove i druge parametre sesije možete promijeniti na isti način kao i ostale postavke PHP - u datoteci php.ini, kao i pomoću naredbe ini_set () ili u konfiguracijskim datotekama web poslužitelja

Ako je omogućen samo prvi, tada na početku sesije (pri svakom pozivu session_start ()) kolačići su postavljeni klijentu. Preglednik ispravno vraća ovaj kolačić pri svakom sljedećem zahtjevu, a PHP ima identifikator sesije. Problemi počinju ako preglednik ne vrati kolačiće. U tom slučaju, bez primanja kolačića s identifikatorom, PHP će cijelo vrijeme započinjati novu sesiju, a mehanizam neće raditi.

Ako je omogućen samo drugi, kolačići nisu postavljeni. I ono što se događa je, radi čega, u osnovi, zapravo, vrijedi koristiti ugrađeni mehanizam sesije. Nakon što skripta obavi svoj posao i stranica se potpuno formira, PHP pregledava sve te dodaje vezu sesije svakoj vezi i svakom obrascu. Izgleda otprilike ovako:

Indeks

preobraziti se u

Indeks

a u obrasce se dodaje skriveno polje

Teoretski, u našim domaćim sesijama s vama na kolačićima i u bazi podataka možete ručno dodijeliti prijenos ID -a svim vezama sami - i tada će naše vlastite sesije raditi bez obzira na kolačiće. Ali, vidite - ugodnije je kad to radi netko drugi? ;-)

Obje su opcije prema zadanim postavkama omogućene u novijim verzijama PHP -a. Kako PHP rješava ovaj slučaj? Kuhar je uvijek izložen. Veze se automatski dovršavaju samo ako PHP nije pronašao kolačiće s ID -om sesije. Kad korisnik prvi put posjeti web mjesto tijekom ove sesije, na njega se postavljaju kolačići i nadopunjuju veze. Na sljedeći zahtjev, ako su kolačići podržani, PHP vidi kolačiće i prestaje dovršavati veze. Ako kolačići ne rade, PHP nastavlja ispravno dodavati ID vezama, a sesija se ne gubi.
Korisnici s kolačićima samo će jednom vidjeti dugačku vezu s ID -om.

Nakon što je prijenos identifikatora završen. Sada ostaje vezati datoteku s podacima na strani poslužitelja. PHP će to učiniti umjesto nas. Dovoljno je samo napisati:

session_start ();
$ _SESSION ["test"] = "Pozdrav svijetu!" ;

PHP će ispisati testnu varijablu u datoteku povezanu s ovom sesijom.

Ovdje postoji jedna vrlo važna točka.

Niz $ _SESSION- poseban.
U njemu su, zapravo, varijable koje želimo učiniti dostupnima u različitim skriptama.
Da biste varijablu smjestili u sesiju, samo je dodijelite elementu niza $ _SESSION.
Da biste dobili njegovu vrijednost, dovoljno je uputiti se na isti element. Primjer će biti dolje.

Skupljanje smeća - PHP je također uključen u uklanjanje zastarjelih datoteka. Kao i kodiranje podataka i hrpu drugih korisnih stvari. Kao rezultat ove brige, rad sa sjednicama je vrlo jednostavan.
Ovdje smo, zapravo, došli do primjera rada sjednica.
Primjer je vrlo mali:

session_start ();

jeka "Ažurirali ste ovu stranicu"... $ _SESSION ["counter"] ++. "jednom.";
jeka "
ažuriranje ";
?>

Provjeravamo imamo li varijablu brojača u sesiji, ako nema, tada je stvaramo s vrijednošću 0, a zatim izlazimo njezinu vrijednost i povećavamo je za jedan. Povećana vrijednost bit će zapisana u sesiju, a sljedeći put kada se pozove skripta, varijabla će imati vrijednost 1 itd. Sve je vrlo jednostavno.

Da biste imali pristup varijablama sesije na bilo kojoj stranici web stranice, morate napisati SAMO JEDAN (!) Red na samom početku SVAKE datoteke u kojoj su nam potrebne sesije:

session_start ();

session_start ();
ako ($ _SESSION ["ovlašten"]<> 1 ) {
zaglavlje ("Lokacija: /auth.php");
Izlaz;
}

Uklanjanje varijabli iz sesije. Ako imate register_globals = off, samo napišite

unset ($ _ SESSION ["var"]);

Ako ne, onda u blizini uz to morate napisati:

session_unregister ("var");

Vrlo je važno razumjeti za koje se sesije treba koristiti, a što ne.

Prvo, zapamtite da se sesije mogu koristiti samo kada su korisniku potrebne, a ne da ga ometaju. Uostalom, u svakom se trenutku može riješiti identifikatora!
Na primjer, prilikom provjere da li osoba ispunjava obrazac, a ne skriptu, sam je korisnik zainteresiran za rad sesije - u protivnom neće moći poslati obrazac! No za ograničavanje broja zahtjeva na skriptu, sesija više nije prikladna - zlonamjerna skripta jednostavno neće vratiti identifikator.

Drugo. Važno je razjasniti činjenicu da je sesija sjednica rada s web mjestom, onako kako ga osoba razumije. Došao, radio, zatvorio preglednik - sesija je završena. Kao filmska seansa. Ako želite vidjeti još jednu - kupite novu kartu. Započni novu sesiju. Za to postoji i tehničko objašnjenje. Jamči se da mehanizam sesije radi samo dok se preglednik ne zatvori. Uostalom, kolačići možda neće raditi za klijenta, au ovom slučaju, naravno, sve veze dopunjene identifikatorom nestat će kada se zatvore.

Međutim, sesija može nestati bez zatvaranja preglednika. Zbog ograničenja o kojima se govori u ovom članku, mehanizam sesije ne može otkriti kada je korisnik zatvorio preglednik. Za to se koristi vremensko ograničenje - unaprijed određeno vrijeme, nakon čega smatramo da je korisnik napustio web mjesto. Prema zadanim postavkama, ovaj parametar je 24 minute.

Ako želite spremiti korisničke podatke na dulje razdoblje, upotrijebite kolačiće i po potrebi bazu podataka na poslužitelju. Konkretno, svi popularni autorizacijski sustavi funkcioniraju na sljedeći način:

Nakon identifikacije korisnika, sesija započinje i u njoj se prenosi znak autorizacije.
- Ako je potrebno "zapamtiti" korisnika, tada mu se postavlja kolačić koji ga identificira.
- Sljedeći put kada korisnik uđe na web mjesto, da bi se prijavio, mora ili unijeti lozinku, ili je sam sustav prepoznaje putem prethodno postavljenih kolačića i sesija počinje. Nova sesija, a ne nastavak stare.

Treće, ne vrijedi započinjati sesije bez razlike, za sve koji uđu na web mjesto. To će stvoriti potpuno nepotrebno opterećenje. Nemojte koristiti sesije za sitnice - na primjer, u šalterima. Ono što spilog naziva sesije, naravno, temelji se na statistici poziva, a ne na korištenju mehanizma sesije sličnog PHP -u.

Uz to, uzmimo tražilicu koja indeksira vašu web lokaciju. Ako robot za pretraživanje ne podržava kolačiće, tada će PHP prema zadanim postavkama isporučiti PHPSESSID na veze, što možda i nije baš ugodno za tražilicu koja, prema glasinama, ionako ne favorizira dinamičke veze, ali ovdje općenito, pri svakom pozivu - nova adresa!

Ako se sesije koriste za ograničavanje pristupa zatvorenom odjeljku web stranice, onda je sve samo tražilica i ne bi se trebalo indeksirati. Ako morate pokazati istu stranicu i ovlaštenim i neovlaštenim korisnicima, tada će vam takav trik pomoći - započeti sesiju samo onima koji su unijeli lozinku ili onima koji su već započeli sesiju.

Da biste to učinili, umjesto samo session_start () pišemo:

if (isset ($ _ REQUEST [session_name ()])) session_start ();

stoga započinjemo sesiju samo onima koji su poslali identifikator.
U skladu s tim, potrebno ga je poslati korisniku prvi put - u vrijeme autorizacije.

Ako su naziv i šupa točni - napišite session_start () !

Najčešće pogreške koje PHP daje pri pokušaju rada sa sesijama su:
Njih dvoje,

Upozorenje: kolačić sesije nije moguće poslati - zaglavlja su već poslana
Upozorenje: Nije moguće poslati ograničenje predmemorije sesije - zaglavlja su već poslana

uzrokovane istim razlogom, rješenje je opisano u ovoj činjenici

Upozorenje: otvoreno (/ tmp \ sess_SID, O_RDWR) nije uspjelo: Nema takve datoteke ili direktorija (2) u punoj_skripti_putanja na broju retka

ranije je izgledala

Upozorenje: Zapisivanje podataka o sesiji (datoteka) nije uspjelo. Provjerite je li trenutna postavka session.save_path točna (/ tmp) ,

ako se prevede s engleskog, detaljno objašnjava problem: put naveden u php.ini do direktorija u koji se zapisuju datoteke sesije nije dostupan. Tu grešku je najlakše popraviti. Samo napišite direktorij koji postoji i na koji je moguće pisati, na primjer,

session.save_path = c: \ windows \ temp

I ne zaboravite ponovno pokrenuti Apache nakon toga.

Kako se pokazalo, ljudska inteligencija nema granica, pa moram objasniti:
treća poruka o pogrešci (direktorij se ne može pronaći) neizbježno će dovesti do prve dvije, jer se poruka o pogrešci šalje u preglednik i nakon nje ne možete koristiti zaglavlja. Stoga, ne žurite tražiti preuranjeni zaključak, već prvo napišite ispravan put!

Sljedeći najčešći problem pri rješavanju sesija je veliko naslijeđe register_globals. NE dajte varijablama skripte iste nazive kao indeksi niza $ _SESSION!

Ako je register_globals = on, vrijednosti će se prebrisati i zbuniti se.

Ako ne radi, ali se ne prikazuju ni poruke, dodajte dva retka na samom početku skripte koji su odgovorni za prikaz SVIH pogrešaka na ekranu - sasvim je moguće da postoje pogreške, ali jednostavno ne vidite ih.

ini_set ("display_errors", 1);
prijavljivanje greške (E_ALL);

ili pogledajte pogreške u error_log. Općenito, tema prikazivanja poruka o pogreškama izvan je opsega ovog članka, stoga samo provjerite možete li ih vidjeti. U ovom odjeljku možete pročitati malo više detalja o rješavanju problema.

Ako ste sigurni da nema pogrešaka, ali navedeni primjer ionako ne funkcionira, moguće je da PHP ne omogućuje prijenos id -a putem url -a, i kolačići iz nekog razloga ne rade.
Pogledajte što imate s kolačićima.

Općenito, ako vaše sesije "ne rade", prvo pokušajte ručno prenijeti identifikator sesije, odnosno napraviti vezu i dodijeliti joj identifikator:

session_start ();
if (! isset ($ _ SESSION ["counter"])) $ _SESSION ["counter"] = 0;
jeka "Ažurirali ste ovu stranicu"... $ _SESSION ["counter"] ++. "jednom.

ažuriranje ";
?>

Pritom provjerite nije li omogućena direktiva session.use_only_cookies, što sprječava PHP da prihvati ID sesije ako je proslijeđen kroz URL.

Ako ovaj primjer ne radi, problem je ili u banalnom pravopisne pogreške(polovica "problema" sa sesijama dolazi od pogrešno napisanog naziva varijable) ili u prestaroj verziji PHP -a: podrška sesije pojavila se u verziji 4.0, a niz $ _SESSION- u 4.1 (prethodno korišteno $ HTTP_SESSION_VARS).

Ako radi, problem je u kolačićima. Praćenje - kakve kolačiće poslužitelj stavlja u preglednik, vraća li ih preglednik. Pretraživanje je vrlo korisno pri gledanju razmjene HTTP zaglavlja između preglednika i poslužitelja.

Objašnjenje načina funkcioniranja kolačića izvan je opsega ovog i toliko teksta, ali barem pazite da poslužitelj šalje kolačiće s identifikatorom, a preglednik se vrati. I dok se identifikatori međusobno podudaraju =)
Postavljanje kolačića trebalo bi izgledati ovako

Kolačić za postavljanje: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6;

Kolačić za postavljanje: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; put = /

(ako tražite skriptu koja nije iz korijenskog direktorija)
Odgovor poslužitelja trebao bi izgledati ovako

Kolačić: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6

Kolačić: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; b = b

ako preglednik vrati kolačiće osim ID -a sesije.

Ako primjer odavde funkcionira, ali vaš vlastiti kod ne, onda problem očito nije u sesijama, već u algoritmu. Potražite gdje ste izgubili varijablu, korak po korak prenesite primjer odavde, otklonite pogreške u skripti.

Drugi problem može nastati ako koristite preusmjeravanje zaglavlja ili JavaScript navigaciju.
Činjenica je da PHP automatski dodaje identifikator sesije samo vezama obrasca
, ali ne radi to za zaglavlja, javascript, meta oznake.

Stoga morate ručno dodati identifikator, na primjer, ovako:

header ("Location: /script.php?". session_name (). "=". session_id ());

Također, vrlo rijedak i potpuno nejasan način na koji dolazi, problem je u tome što postavka session.save_handler ima drugu vrijednost osim datoteka. Ako to nije slučaj, ispravite to.

  • Osim kolačića, mehanizam sesije šalje i zaglavlja koja zabranjuju predmemoriranje stranica (isti ograničivač predmemorije). Za html to je ispravno i potrebno. No, kada pokušate poslati datoteku sa skriptom koja provjerava autorizaciju, Internet Explorer je odbija preuzeti. To je zbog ovog naslova. Poziv
    session_cache_limiter ("privatno");
    mora riješiti problem prije početka sesije.
  • Čudno, ali u nizu $ _SESSION ne možete koristiti numeričke indekse - $ _SESSION [1], $ _SESSION ["10"]- sesije neće raditi.
  • Negdje između 4.2 i 5.0 nije bilo moguće postaviti session.use_trans_sid s ini_set ()... Počevši od 5.0 već je opet moguće.
  • Prije verzije 4.3.3 kolačići PHP je slao kolačiće samo ako zahtjev nije sadržavao identifikator na početku sesije. Sada se kolačići šalju na svaki poziv session_start

    Ako imate još pitanja ili vam nešto nije jasno - dobrodošli u naš

Od samog početka svi su prihvaćali PHP s praskom, ali čim su počeli stvarati dovoljno velike projekte na ovom jeziku, programeri su se suočili s novim problemom - u PHP -u ​​nije postojao koncept globalnih varijabli! To jest, skripta je izvršena, poslana generirana stranica klijentu, a svi resursi koje koristi ova skripta su uništeni. Za ilustraciju, recimo da postoje dvije stranice na istoj web stranici, index.php i dothings.php. Izvori ovih stranica izgledaju ovako:

index.php dothings.php

Ako izvršite ove dvije skripte, tada ćemo na prvoj stranici vidjeti natpis "Dodijeljen mi je index.php", a druga stranica bit će prazna.

Programeri web stranica, bez oklijevanja, počeli su koristiti kolačiće za spremanje globalnih varijabli na strani klijenta. Proces je izgledao otprilike ovako: korisnik dolazi na početnu stranicu web stranice, poduzima neke radnje, a svi podaci u vezi s tim korisnikom, koji mogu biti potrebni na drugim stranicama web stranice, bit će pohranjeni u njegovom pregledniku u obliku kolačića. Ova metoda ima prilično ozbiljne nedostatke, zbog kojih su mnogi programeri odjednom okrenuli leđa PHP -u. Na primjer, potrebno je autorizirati korisnika da mu omogući pristup ograničenim (ili samo svojim) odjeljcima web stranice. Korisniku ćete morati poslati kolačić koji će mu poslužiti kao naknadni identifikator na web mjestu. Ovaj pristup postaje vrlo glomazan i nezgodan čim web mjesto počne prikupljati sve više i više informacija o ponašanju korisnika, jer bi se svi podaci koji se šalju korisniku trebali kodirati tako da se ne mogu krivotvoriti. U novije vrijeme lažnim kolačićem bilo je moguće "složiti" više od jednog chata, a ponekad čak i ući u tuđu poštu. Osim toga, u svijetu još uvijek postoje čudni ljudi čiji preglednik ne podržava kolačiće.

Neću ulaziti u tehnološka pitanja strukture mehanizma sesije, već ću samo opisati kako pravilno raditi sa sesijama u PHP -u.

Kako raditi sa sesijama?

Ako primjere iz članka (ili svoje skripte) isprobate na bilo kojem komercijalnom hostingu, ne bi trebalo biti problema s radom sa sesijama. Ako ste sami postavili poslužitelj (bio to pravi poslužitelj ili emulator), mogu se pojaviti pogreške sa sljedećim sadržajem:

"Upozorenje: otvoreno ( / var / state / php / sess_6f71d1dbb52fa88481e752af7f384db0, O_RDWR) nije uspjelo: Nema takve datoteke ili direktorija (2)".

To samo znači da je vaš PHP pogrešno konfiguriran. Ovaj problem možete riješiti upisivanjem ispravnog puta (do postojećeg direktorija) za spremanje sesija u datoteku php.ini i ponovnim pokretanjem poslužitelja.

Svaka skripta koja će koristiti varijable (podatke) iz sesija trebala bi sadržavati sljedeći redak:

Session_start ();

Ova naredba govori poslužitelju da datoj stranici trebaju sve varijable koje su povezane s danim korisnikom (preglednikom). Poslužitelj preuzima ove varijable iz datoteke i čini ih dostupnima. Vrlo je važno otvoriti sesiju prije slanja bilo kakvih podataka korisniku; u praksi to znači da je poželjno pozvati funkciju session_start () na samom početku stranice, na primjer:

Session_start (); ?> ... Za postavljanje direktorija u koji će se datoteke sesije spremati, upotrijebite funkciju session_save_path (): session_save_path ($ _ SERVER ["DOCUMENT_ROOT"]. "/ Sesija"); session_start ();

Nakon što je sesija započela, možete postaviti globalne varijable. Prilikom dodjeljivanja vrijednosti bilo kojem polju u nizu $ _SESSION, varijabla s istim imenom automatski se registrira kao varijabla sesije. Ovaj niz je dostupan na svim stranicama koje koriste sesiju. Na primjer, analiziramo program:

index.php Sve u redu. Sesija je učitana! Idemo kroz, da vidimo što ima:

dothings.php

Kada se te datoteke pokreću uzastopno, prva skripta "index.php" proizvest će sljedeći rezultat:

Sve u redu. Sesija je učitana! Idemo kroz, da vidimo što ima:

A drugi "dothings.php" je ovaj:

Pitali su me na index.php

Varijabla $ a sada je dostupna na svim stranicama ove web stranice koje su započele sesije.

Ostale korisne funkcije i tehnike za rad sa sjednicama:

  • poništeno ($ _ SESSION ["a"])- sesija "zaboravlja" vrijednost varijable koju je sesija postavila;
  • session_destroy ()- sesija je uništena (na primjer, ako je korisnik napustio sustav pritiskom na gumb "izlaz");
  • parametri_skup_kod_kuše_sesije (int životni vijek [, niz niza [, nizova domena]])- pomoću ove funkcije možete postaviti koliko će sesija "živjeti" postavljanjem unix_timestamp definirajući vrijeme "umiranja" sesije. Prema zadanim postavkama, sesija "živi" sve dok klijent ne zatvori prozor preglednika.
  • session_write_close ()- snimanje varijabli sesije i njihovo zatvaranje. To je potrebno za otvaranje web mjesta u novom prozoru, ako stranica obavlja dugu obradu i blokirala je datoteku sesije za vaš preglednik.

Primjeri

Pređimo sada na praktičnu primjenu mehanizma sesije. Ovdje ćemo pogledati nekoliko prilično jednostavnih, ali korisnih primjera.

Autorizacija korisnika

Pitanja o autorizaciji korisnika pomoću PHP sesija stalno se postavljaju na konferencijama za web programiranje. Mehanizam za autorizaciju korisnika u sustavu pomoću sesija je sa sigurnosnog stajališta prilično dobar (vidi odjeljak).

Naš primjer sastojat će se od tri datoteke: index.php, authorize.php i secretplace.php. Datoteka index.php sadrži obrazac u koji će korisnik unijeti svoje korisničko ime i lozinku. Ovaj će obrazac proslijediti podatke u datoteku authorize.php, što će, u slučaju uspješne autorizacije, omogućiti korisniku pristup datoteci secretplace.php, a na drugi način prikazati poruku o pogrešci.

Primjeri: index.php Unesite svoju lozinku

Prijaviti se:
Lozinka:


autorize.php page ... header ("Lokacija: secretplace.php"); Izlaz; )) // ako nešto nije u redu, tada će korisnik dobiti // poruku o pogrešci. ?> Unijeli ste pogrešnu lozinku!

secretplace.php Hej,, na tajnoj ste stranici !!! :)

Sigurnost

Dakle, u mogućnosti smo prenijeti identifikator s jedne stranice (PHP skripta) na drugu (do sljedećeg poziva s naše stranice), što znači da možemo razlikovati sve posjetitelje web stranice. Budući da je identifikator sesije vrlo velik broj (128 bita), praktički nema šanse da će to biti gruba sila. Stoga napadaču preostaju sljedeće mogućnosti:

  • na računaru korisnika postoji trojanac koji krade brojeve sesija;
  • Napadač hvata promet između korisnikovog računala i poslužitelja. Naravno, postoji siguran (šifriran) SSL protokol, ali ne koriste ga svi;
  • susjed je došao do računara našeg korisnika i ukrao broj sesije.

Takve situacije, temeljene na činjenici da netko nekome nešto ukrade, općenito nisu u nadležnosti programera. O tome bi se trebali pobrinuti administratori i sami korisnici.

Međutim, PHP se često može prevariti. Pogledajmo moguće točke hakiranja u programu autorizacije korisnika:

  • Datoteka authorize.php-pokušaj grube prisile lozinke pomoću skripte treće strane;
  • Datoteka secretplace.php pokušaj je prevare programa unošenjem vrijednosti varijable $ logged_user u adresnu traku preglednika, na primjer:
    "http://www.yoursite.ru/secretplace.php? prijavljeni_korisnik = haker"

Dakle, u našem programu jasno su vidljive dvije "rupe", jedna je mala i nije osobito uočljiva, ali druga je jednostavno ogromna, kroz koju se većina hakera penje tamo gdje im ne treba.

Kako "zakrpati" rupu broj 1?

Nećemo pisati tone koda za blokiranje IP adrese, itd., Nego samo provjerite odakle dolazi zahtjev, odnosno s koje stranice je zahtjev došao, ako se radi o bilo kojoj stranici s naše web stranice, onda je sve u redu, ali u svim ostalim slučajevima nećemo ga pustiti unutra. Ispravimo datoteku authorize.php:

autorize.php V2 page ... header ("Lokacija: secretplace.php"); Izlaz; )))?> Unijeli ste pogrešnu lozinku!


Kako se riješiti "rupe" broj 2?

Pretpostavimo da imate web stranicu na kojoj se svaki smrtnik može registrirati za postavljanje na forum. Naravno, na forumu neki korisnici (administratori, moderatori) imaju više mogućnosti od drugih, na primjer, mogu izbrisati poruke drugih korisnika. Razinu korisničkog pristupa pohranjujete u sesiju, u varijablu $ user_status, gdje $ user_status = 10 odgovara potpunom pristupu sustavu. Napadač koji dođe na web lokaciju samo se mora registrirati na uobičajen način, a zatim dodati u adresnu traku preglednika ? user_status = 10... Dakle, imate novog administratora na svom forumu!

U načelu, bilo koja varijabla skripte može se postaviti kroz adresni redak, jednostavno dodavanjem upitnika i imena varijable s njezinom vrijednošću nakon pune adrese skripti. Popravimo naš kôd kako bismo to izbjegli:

secretplace.php V2 varijabla nije postavljena ($ _ SESSION ["logged_user"]); // otvaranje sesije session_start (); / * ne možete jednostavno otići na ovu stranicu ... ako korisničko ime nije registrirano, tada ga preusmjeravamo na stranicu index.php kako bismo unijeli prijavu i lozinku ... ovdje zapravo možete učiniti mnogo, za na primjer, zapamtite korisnikov IP i nakon trećeg pokušaja pristupa datotekama blokirajte ga. * / if (! isset ($ _ SESSION ["logged_user"])) (header ("Lokacija: index.php"); exit;)?> Hej,, nalazite se na tajnoj stranici!

Ishodi

Mehanizam sesije je prilično kul značajka PHP jezika. Sesije su jednostavne, vrlo fleksibilne za korištenje. Usput, postoji jedna, na nekoliko mjesta dokumentirana mogućnost PHP sesija (dostupna od verzije 4.0.3) - u sesije možete pohraniti ne samo varijable, već i objekte.

Primjeri

?>
// Automatsko umetanje SID -ova u veze. ini_set ("session.use_trans_sid", točno); session_start (); ?> Kliknite ovdje!
Kliknite ovdje !!



// Primjer rada sa sesijama. session_start (); // Ako je web mjesto tek posjećeno, poništite brojač. if (! isset ($ _ SESSION ["count"])) $ _SESSION ["count"] = 0; // Povećanje brojača u sesiji. $ _SESSION ["count"] = $ _SESSION ["count"] + 1; ?>

Brojač

vrijeme (a).
Zatvorite preglednik da biste poništili brojač.
"target =" _blank "> Otvorite prozor podređenog preglednika.
// Jednostavan primjer korištenja sesija bez kolačića. session_name ("test"); session_start (); $ _SESSION ["count"] = @ $ _ SESSION ["count"] + 1; ?>

Brojač

U trenutnoj sesiji s preglednikom otvorili ste ovu stranicuvrijeme (a).
Zatvorite svoj preglednik da biste poništili ovaj brojač.
?"> Kliknite ovdje za osvježavanje stranice!

Sesije su jednostavan način za pohranu podataka za pojedinačne korisnike s jedinstvenim ID -om sesije. To se može koristiti za trajno stanje između zahtjeva stranice. ID -ovi sesije obično se šalju pregledniku putem kolačića sesije i koriste se za dohvaćanje dostupnih podataka o sesiji. Odsustvo ID -a sesije ili kolačića sesije govori PHP -u ​​da stvori novu sesiju i generira novi ID sesije.

Sesije koriste jednostavnu tehnologiju. Kad se sesija kreira, PHP će ili dobiti postojeću sesiju pomoću proslijeđenog identifikatora (obično iz kolačića sesije), ili, ako ništa nije proslijeđeno, bit će stvorena nova sesija. PHP će popuniti superglobalni $ _SESSION podacima o sesiji nakon početka sesije. Kad PHP izađe, automatski će serijalizirati sadržaj $ _SESSION superglobal -a i poslati ga na pohranu pomoću rukovatelja sesije za snimanje sesije.

Prema zadanim postavkama PHP koristi unutarnji upravljač datotekama za spremanje sesija, koji je postavljen u INI varijabli session.save_handler. Ovaj rukovatelj sprema podatke na poslužitelj u direktorij naveden u konfiguracijskoj direktivi session.save_path.

Sesije se mogu pokrenuti ručno pomoću funkcije session_start ()... Ako je direktiva session.auto_start postavljena na 1, sesija će automatski započeti na početku zahtjeva.

Sesija obično završava kada PHP završi izvršavanje skripte, ali se također može ručno prekinuti pomoću funkcije session_write_close ().

Upozorenje

Pažnja

Komentar:

Sesije koje koriste datoteke (prema zadanim postavkama u PHP -u) blokiraju datoteku sesije odmah nakon otvaranja sesije s funkcijom session_start () ili neizravno određivanjem sesije.auto_start. Nakon blokiranja, niti jedna druga skripta ne može pristupiti istoj datoteci sesije sve dok se ne zatvori ili kada skripta završi ili kada se pozove funkcija. session_write_close ().

To će najvjerojatnije biti problem za web lokacije koje intenzivno koriste AJAX i upućuju više istovremenih zahtjeva. Najjednostavniji način rješavanja ovog problema je pozivanje funkcije session_write_close ()čim se izvrše sve potrebne promjene u sesiji, po mogućnosti bliže početku skripte. Također možete koristiti drugi mehanizam sesije koji podržava istodobnost.

Ne mogu shvatiti zašto, ali pokušao sam sve / google odgovore .. Nisam uspio pronaći ništa. Evo situacije:

Lokalni kôd

Proizlaziti:

Uzastopni session_id () na stranicama aplikacije i na stranici osvježavanje. $ _COOKIE ["PHPSESSID"] odgovara session_id ()

Izravni poslužitelj

Session_start (); echo session_id (); print_r ($ _ COOKIE ["PHPSESSID"]);

Proizlaziti:

session_id () se mijenja pri svakom zahtjevu, ponovnom učitavanju stranice ili posjetu drugoj stranici. $ _COOKIE ["PHPSESSID"] je NULL / prazno. Isti kôd koristi se pri vrhu stranice. nema drugog sadržaja.

Ovaj problem zadao mi je pravu glavobolju, kakva konfiguracija poslužitelja ili pogreška mogu uzrokovati to? Zašto je kolačić PHPSESSID prazan, vjerujem da je to zato što se pridruženi session_id () resetira i na svaki zahtjev?

Molim vas za svaku pomoć momci!

EDIT: Napravio sam jednostavnu testnu datoteku s 3 retka na svom lokalnom udaljenom poslužitelju. Ovo nije povezano s mojim kodom. $ _COOKIE ["PHPSESSID"] je još uvijek prazan, a novi session_id () se događa na pravom hostu pri svakom ažuriranju.

error_reporting POSTAVI NA SVE Dobijam ovo na hostu uživo:

Napomena: Nedefinirani indeks: PHPSESSID u /home/vivaplug/public_html/dev/wp-content/plugins/test.php na retku 5

Zaglavlja Google Chrome

LOCALHOST

URL zahtjeva: http: //localhost/wp-content/plugins/test.php Metoda zahtjeva: GET Statusni kôd: 200 OK Izvor zahtjeva za zaglavlje zahtjeva Prihvati: text /html, application /xhtml + xml, application /xml; q = 0,9, image / webp, * / *; q = 0,8 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US, en; q = 0,8 Kontrola predmemorije: veza bez predmemorije: veza za održavanje Cookie: PHPSESSID = 68b7m4arpsacks4aetgmd3rs93 Domaćin: localhost Pragma: korisnički agent bez predmemorije: Mozilla / 5.0 (Windows NT 6.1) AppleWebKit / 537.36 (KHTML, poput Gecko) Chrome / 30.0.1599.101 Safari / 537,36 Response Headersview izvor za pregled predmemorije: bez pohrane, bez predmemorija, mora se ponovno provjeriti, nakon provjere = 0, prethodna provjera = 0 Veza: Keep-Alive-Vrsta sadržaja: tekst / html Datum: Utorak, 05. studenog 2013. 07:10:51 GMT Ističe: Čet, 19. studenog 1981. 08 : 52: 00 GMT Keep-Alive: timeout = 5, max = 100 Pragma: poslužitelj bez predmemorije: Apache / 2.4.4 (Win32) PHP / 5.4.16 Prijenos-kodiranje: u komadima X-Powered-By: PHP / 5.4 .16

UKLONI SERVER

URL zahtjeva: http: //vivaplugins.com/dev/wp-content/plugins/test.php Metoda zahtjeva: GET Statusni kod: 200 U redu Zahtjev izvor za pregled naslova Prihvaća: tekst/html, aplikacija/xhtml + xml, aplikacija/xml; q = 0,9, image / webp, * / *; q = 0,8 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US, en; q = 0,8 Kontrola predmemorije: max-age = 0 Veza: keep- živ Domaćin: vivaplugins.com Korisnički agent: Mozilla / 5.0 (Windows NT 6.1) AppleWebKit / 537.36 (KHTML, poput Gecko) Chrome / 30.0.1599.101 Safari / 537.36 Response Headers Source Source Doba: 0 Kontrola predmemorije: bez pohrane, ne -cache, must-revalidate, post-check = 0, pre-check = 0 Content-Encoding: gzip Content-Type: text / html Datum: Tue, 05.11.2013. 07:07:49 GMT Pragma: poslužitelj bez predmemorije: Napredni hosting putem http://www.unixy.net/varnish Transfer-Encoding: u komadima Varira: Prihvati-kodira putem: 1.1 laka X-Cache: HIT X-Cache-Hits: 2 X-Cacheable: DA X-Powered-By : PHP / 5.4.20 X-Varnish: 1984840969 1984839805