Piesakieties php sesijā. Sesiju izmantošana - darbs ar PHP sesijām

Turpinot apgūt PHP, jūs, iespējams, izmantosit šādu funkciju kā sesijas vai pat laiku pa laikam par to dzirdēsit. Šajā rakstā es par tiem runāšu sīkāk un izmantošu ilustratīvus piemērus, lai analizētu to darbības principu. Es arī pastāstīšu, kur un kā tos parasti var izmantot.

Kas ir sesija? Sesijas ļauj izveidot sava veida savienojumu starp pašu vietni un lietotāju, izmantojot sesijas identifikatoru. Visi sesijas mainīgie un to vērtības tiek saglabāti tikai serverī. Lietotājs, tāpat kā serveris, saglabā tikai sesijas identifikatorus, kas tiek ģenerēti nejauši, tie ļauj precīzi izveidot šo servera-klienta savienojumu.

Klienta pusē (viņa datorā) saglabātais sesijas ID ir fails cepums. Sīkdatnes tiek saglabātas lietotāja pārlūkprogrammā, bet atbilstošs fails tiek izveidots arī serverī.

Sāksim tieši uz praksi.

Izveidojiet sesiju:

Visvienkāršākais veids šeit ir izmantot sesijas_start funkciju:

1 2 // Sākt sesiju session_start();

// Sākt sesiju session_start();

Šī funkcija pārbauda, ​​vai ir sesijas identifikators, ja tā nav, tā to izveido. Un, ja tas ir pieejams, tas ielādē reģistrētos mainīgos no esošās sesijas.

Šī konstrukcija ir jāizsauc tikai vienu reizi lapā un pirms jebkuras izvades (šis noteikums attiecas arī uz setcookie()).

Ļaujiet man sniegt piemēru: kad pārlūkprogrammā tiek izveidota sesija, sīkfails izskatās šādi:

Kad tiek izveidota sesija, pārlūkprogrammai tiek nosūtīts šāds sīkfails:

1 2 atbalss "Sesijas nosaukums:". sesijas_nosaukums(). "Sesijas ID: ". sesijas ID(); // Sesijas nosaukums: PHPSESSID Sesijas ID: mceu371l97id3sa0vcbjqnht06

echo "Sesijas nosaukums: ".sesijas_nosaukums(). " Sesijas ID: ".session_id(); // Sesijas nosaukums: PHPSESSID Sesijas ID: mceu371l97id3sa0vcbjqnht06

Izveidosim sesijas mainīgo:

Sesijas mainīgo var izveidot, pievienojot vērtību masīva $_SESSION superglobālajam elementam:

unset($_SESSION["pieteikšanās"]);

Iepriekš minētā metode ir laba, taču jūs varat notīrīt visu $_SESSION masīvu, tādējādi no sesijas noņemot visus mainīgos:

1 2 // Iztīriet mūsu $_SESSION masīvu$_SESIJA = masīvs () ;

// Iztīrīt mūsu masīvu $_SESSION $_SESSION = array();

2. Tagad mums ir jāanulē sīkfails (kur, piekļūstot sesijas ID sīkfailā un URL, ir atsauce uz sesijas nosaukumu):

1 2 3 if (isset ($_COOKIE [ sesijas_nosaukums () ] ) ) ( // session_name() - izvelciet pašreizējās sesijas nosaukumu setcookie (sesijas_nosaukums () , "" , laiks () - 86400 , "/" ) ; )

if (isset($_COOKIE)) ( // sesijas_nosaukums() — izvelciet pašreizējās sesijas nosaukumu setcookie(session_name(), "", time()-86400, "/"); )

3. Tālāk mēs iznīcināsim sesiju (slēgsim to):

session_start(); ob_start();

Šeit ir detalizētāks koda piemērs, izmantojot iepriekš apspriestos kodus un funkcijas:

1 2 3 4 5 6 7 8 9 if (isset ($_SESSION [ "pieteikties" ] ) ) ( echo "Sveiki, " . $_SESSION [ "nosaukums" ] . " " ; unset ($_SESSION [ "pieteikšanās" ] ) ; if (isset ($_COOKIE [ sesijas_nosaukums () ] ) ) (setcookie (sesijas_nosaukums () , "" , laiks () - 86400 , "/" ) ; // mūsu sesijas saturs ir tukša virkne) ob_end_flush () ; // Sūtīt izvadi pārlūkprogrammai session_destroy();

if (isset($_SESSION["pieteikšanās"])) ( echo "Sveiki, " . $_SESSION["nosaukums"] . " "; unset($_SESSION["pieteikšanās"]); if (isset($_COOKIE)) ( setcookie(session_name(), "", time()-86400, "/"); // mūsu sesijas saturs ir tukša virkne ) ob_end_flush( // Nosūtīt izvadi uz pārlūkprogrammu session_destroy();

Tomēr ir vērts atzīmēt, ka funkcijas ob_end_flush() izmantošana ne vienmēr ir nepieciešama. Un tas viss tāpēc, ka PHP tulks automātiski notīra jūsu buferi, izpildot kādu skriptu.

Atkārtoti izveidosim sesijas identifikatoru:

Katru reizi, kad piesakāties sistēmā, drošības apsvērumu dēļ ir nepieciešams atkārtoti izveidot sesijas identifikatoru. Visa informācija jūsu sesijas mainīgajos tiek saglabāta jūsu tīmekļa serverī vienkārša teksta veidā noteiktā failā, visa informācija par sesijā izmantotajiem mainīgajiem tiek saglabāta un mainās tikai sesijas identifikators. Lai atjaunotu sesijas identifikatoru, izmantojiet funkciju session_regenerate_id(), pēc tam, kā tas ir izdarīts, atsvaidziniet esošo lapu vai nosūtiet lietotāju uz citu lapu, izmantojot novirzīšanu.

Kā notiek sesijas:

Zemāk esošajā ekrānuzņēmumā varat redzēt īsu paša sesijas mehānisma pārskatu.

Samazināsim sesijas ilgumu:

Standarta sesijas mūža vērtība ir 0, proti, ja lietotājs aizver pārlūkprogrammas logu, tiks aizvērta arī sesija. Bet dažreiz ir nepieciešams piespiedu kārtā iznīcināt klienta sesiju pēc kāda laika, piemēram, viņa neaktivitātes dēļ vietnē. Apskatīsim šādas ieviešanas metodi, izmantojot lietotāja autorizācijas piemēru: izveidosim sava veida mainīgo un saglabāsim tajā lietotāja autorizācijas laikā izmantoto laiku, piemēram, ja lietotājs mēģina pārvietoties lapā, tad salīdzinām laiku ar laiku, kad viņš bija neaktīvs, un, ja šis limits tiks pārsniegts, viņš tiks izrakstīts un nosūtīts uz autorizācijas lapu.

1 2 3 4 5 6 7 8 $_SESIJA["sākums"] = laiks(); // Laika sākums, kad lietotājs pieteicās$timezon = laiks(); // Šoreiz (tā, kas pastāv tagad)$time_limit = 2000 ; // Šis ir maksimālais laiks, kad lietotājs ir neaktīvs if ($timezon > $_SESSION [ "sākums" ] + $time_limit ) ( atbalss "Laiks ir beidzies"; ) else ( $_SESSION [ "sākums" ] = laiks () ; ) // ja viss ir labi, tad atjauniniet

$_SESIJA["sākums"] = laiks(); // Laika sākums, kad lietotājs pieteicās $timezon= time(); // Šoreiz (tā, kas pastāv tagad) $time_limit = 2000; // Šis ir maksimālais laiks, kad lietotājs ir neaktīvs, ja ($timezon> $_SESSION["sākums"] + $time_limit) ( echo "Laiks ir beidzies"; ) else ($_SESSION["sākums"] = laiks(); ) // ja viss kārtībā, atjaunināsim

Dažreiz cilvēkiem rodas jautājums "Kā ieviest bezgalīgu sesijas ilgumu?", šeit es jums sniegšu atbildi. To nevajadzētu darīt, tas ir pilnīgi nepareizs ar ideju. Sesija tika izveidota ar mērķi, lai lietotājs apmeklētu vietni - tā tika atvērta, viņš aizgāja - tā tika slēgta (iznīcināta). Kad viņš vēlreiz pieteicās, tika atvērta jauna sesija. Taču sesijai var izmantot datus no sīkdatnēm, kas var tikt glabāti diezgan ilgu laiku, piemēram, izmantojot izvēles rūtiņu “Atcerēties mani” (Atceries to vietnēs?)...

Sesiju izmantošana ar atspējotiem sīkfailiem:

Pastāsti man, ka tas nenotiek? Diemžēl dažreiz arī tā notiek. Piemēram, ja iestatījuma session.use_trans_sid iestatījums ir 1, tad, ja nav sīkfaila, PHP nodos PHPSESSID parametrus, izmantojot GET metodi jūsu pieprasījuma rindā.

Tas arī viss, raksts ir beidzies. Ja jums joprojām ir jautājumi par sesiju izmantošanu vai, iespējams, ir kādi papildinājumi vai komentāri, varat atstāt visu šī raksta komentāros.

Jau no paša sākuma visi PHP pieņēma ar blīkšķi, taču, tiklīdz šajā valodā sāka veidot diezgan lielus projektus, izstrādātāji saskārās ar jaunu problēmu – PHP trūka globālo mainīgo jēdziena! Tas ir, tika izpildīts noteikts skripts, ģenerētā lapa tika nosūtīta klientam, un visi šī skripta izmantotie resursi tika iznīcināti. Mēģināšu ilustrēt: pieņemsim, ka vienā vietnē ir divas lapas, index.php un dothings.php. Šo lapu avoti izskatās šādi:

indekss.php dothings.php

Ja palaižam šos divus skriptus, tad pirmajā lapā redzēsim uzrakstu “I was assigned to index.php”, un otrā lapa būs tukša.

Vietņu izstrādātāji, divreiz nedomājot, sāka izmantot sīkfailus, lai klienta pusē saglabātu globālos mainīgos. Process izskatījās apmēram šādi: lietotājs nonāk vietnes galvenajā lapā, veic dažas darbības, un visa ar šo lietotāju saistītā informācija, kas var būt nepieciešama citās vietnes lapās, tiks saglabāta viņa pārlūkprogrammā šādā formā. no sīkdatnēm. Šai metodei ir diezgan nopietni trūkumi, kuru dēļ daudzi izstrādātāji vienā reizē novērsās no PHP. Piemēram, mums ir jāpilnvaro lietotājs, lai viņš varētu piekļūt privātām (vai privātām) vietnes sadaļām. Jums būs jānosūta lietotājam sīkfails, kas kalpos kā viņa turpmākais identifikators vietnē. Šāda pieeja kļūst ļoti apgrūtinoša un neērta, tiklīdz vietne sāk vākt arvien vairāk informācijas par lietotāja uzvedību, jo visu lietotājam nosūtīto informāciju ieteicams iekodēt, lai to nevarētu viltot. Pavisam nesen, viltojot sīkfailus, bija iespējams “uzlauzt” vairāk nekā vienu tērzēšanu un dažreiz pat ielīst kāda cita pastā. Turklāt pasaulē joprojām ir dīvaini cilvēki, kuru pārlūkprogramma neatbalsta sīkfailus.

Es neiedziļināšos sesiju mehānisma tehnoloģiskajos jautājumos, bet tikai aprakstīšu, kā pareizi strādāt ar sesijām PHP.

Kā strādāt ar sesijām?

Ja pārbaudīsit raksta piemērus (vai savus skriptus) jebkurā komerciālā mitināšanā, darbā ar sesijām nevajadzētu rasties problēmām. Ja serveri iestatāt pats (neatkarīgi no tā, vai tas ir īsts serveris vai emulators), varat saņemt kļūdas ar kaut ko līdzīgu:

"Brīdinājums: open(/var/state/php/sess_6f71d1dbb52fa88481e752af7f384db0, O_RDWR) neizdevās: nav šāda faila vai direktorija (2)."

Tas tikai nozīmē, ka jūsu PHP ir nepareizi konfigurēts. Šo problēmu var atrisināt, norādot pareizo ceļu (uz esošu direktoriju) sesiju saglabāšanai failā php.ini un restartējot serveri.

Jebkurā skriptā, kurā tiks izmantoti mainīgie (dati) no sesijām, ir jābūt šādai rindai:

Session_start();

Šī komanda norāda serverim, ka konkrētai lapai ir nepieciešami visi mainīgie, kas ir saistīti ar konkrēto lietotāju (pārlūkprogrammu). Serveris ņem šos mainīgos no faila un padara tos pieejamus. Ir ļoti svarīgi atvērt sesiju pirms jebkādu datu nosūtīšanas lietotājam; praksē tas nozīmē, ka ir ieteicams izsaukt funkciju session_start() pašā lapas sākumā, piemēram, šādi:

Session_start(); ?> ... Lai iestatītu direktoriju, kurā tiks saglabāti sesijas faili, izmantojiet funkciju session_save_path(): session_save_path($_SERVER["DOCUMENT_ROOT"]."/session"); session_start();

Pēc sesijas sākuma varat iestatīt globālos mainīgos. Piešķirot jebkuru vērtību jebkuram masīva $_SESSION laukam, mainīgais ar tādu pašu nosaukumu tiek automātiski reģistrēts kā sesijas mainīgais. Šis masīvs ir pieejams visās lapās, kurās tiek izmantota sesija. Piemēram, apskatīsim programmu:

indekss.php Viss OK. Sesija ir ielādēta! Iesim cauri un redzēsim, kas tur ir:

dothings.php

Palaižot šos failus secīgi, pirmais skripts "index.php" radīs šādu rezultātu:

Viss OK. Sesija ir ielādēta! Iesim cauri un redzēsim, kas tur ir:

Un otrais “dothings.php” ir šāds:

Man palūdza index.php

Mainīgais $a tagad ir pieejams visās konkrētās vietnes lapās, kurās ir uzsāktas sesijas.

Citas noderīgas funkcijas un metodes darbam ar sesijām:

  • unset ($_SESSION["a"])- sesija “aizmirst” norādītā sesijas mainīgā vērtību;
  • session_destroy()- sesija tiek iznīcināta (piemēram, ja lietotājs pameta sistēmu, noklikšķinot uz pogas "iziet");
  • session_set_cookie_params (int lifetime [, virknes ceļš [, virknes domēns]])- izmantojot šo funkciju, var iestatīt, cik ilgi sesija “dzīvos”, iestatot unix_timestamp, kas nosaka sesijas “nāves” laiku. Pēc noklusējuma sesija "tiešraidē", līdz klients aizver pārlūkprogrammas logu.
  • session_write_close()- sesijas mainīgo ierakstīšana un tā aizvēršana. Tas ir nepieciešams, lai atvērtu vietni jaunā logā, ja lapas apstrāde aizņem ilgu laiku un ir bloķējis sesiju failu jūsu pārlūkprogrammai.

Piemēri

Tagad pievērsīsimies sesijas mehānisma praktiskajam pielietojumam. Šeit mēs apskatīsim pāris diezgan vienkāršus un tajā pašā laikā noderīgus piemērus.

Lietotāja autorizācija

Tīmekļa programmēšanas konferencēs pastāvīgi tiek uzdoti jautājumi par lietotāju autorizāciju, izmantojot PHP sesijas. Mehānisms lietotāju autorizācijai sistēmā, izmantojot sesijas, no drošības viedokļa ir diezgan labs (skat. sadaļu).

Mūsu piemērs sastāvēs no trim failiem: index.php, authorize.php un secretplace.php. Index.php failā ir veidlapa, kurā lietotājs ievadīs savu lietotājvārdu un paroli. Šī veidlapa nosūtīs datus failam authorize.php, kas, ja autorizācija būs veiksmīga, ļaus lietotājam piekļūt failam secretplace.php, un pretējā gadījumā tiks parādīts kļūdas ziņojums.

Piemēri: indekss.php Ievadiet savu paroli

Pieslēgties:
Parole:


Authorize.php lapa... header("Atrašanās vieta: secretplace.php"); Izeja; ) ) // ja kaut kas bija nepareizi, lietotājs saņems // kļūdas ziņojumu. ?>

Jūs ievadījāt nepareizu paroli! slepenā vieta.phpSveiki,

, tu esi slepenā lapā!!! :)

Drošība

  • Tātad, mēs varam nodot identifikatoru no vienas lapas (PHP skripts) uz otru (līdz nākamajam zvanam no mūsu vietnes), kas nozīmē, ka mēs varam atšķirt visus vietnes apmeklētājus. Tā kā sesijas identifikators ir ļoti liels skaits (128 biti), praktiski nav nekādu iespēju, ka to var atrast ar brutālu spēku. Tāpēc uzbrucējam tiek atstātas šādas iespējas:
  • lietotāja datorā ir Trojas zirgs, kas nozog sesiju numurus;
  • uzbrucējs pārtver trafiku starp lietotāja datoru un serveri. Protams, ir drošs (šifrēts) SSL protokols, taču ne visi to izmanto;

kaimiņš piegāja pie mūsu lietotāja datora un nozaga sesijas numuru.

Šādas situācijas, kuru pamatā ir fakts, ka kāds kaut ko nozog kādam citam, kopumā nav programmētāja kompetencē. Par to ir jārūpējas administratoriem un pašiem lietotājiem.

  • Tomēr PHP ļoti bieži var tikt "apmānīts". Apskatīsim iespējamos uzlaušanas punktus lietotāju autorizācijas programmā:
  • Autorize.php fails ir mēģinājums uzminēt paroli, izmantojot trešās puses skriptu;
    Fails secretplace.php ir mēģinājums maldināt programmu, pārlūkprogrammas adreses joslā ievadot mainīgā $logged_user vērtības, piemēram, šādi: "http://www.yoursite.ru/secretplace.php?"

logged_user=hacker

Tātad mūsu programmā ir skaidri redzami divi “caurumi”, viens ir mazs un nav īpaši pamanāms, bet otrs ir vienkārši milzīgs, caur kuru lielākā daļa hakeru nokļūst tur, kur viņiem nav jāiet.

Mēs nerakstīsim tonnām kodu, lai bloķētu IP adresi utt., bet vienkārši pārbaudīsim, no kurienes nāk pieprasījums vai drīzāk no kuras lapas tas ir, ja tā ir kāda lapa no mūsu vietnes, tad viss ir kārtībā, bet visos citos gadījumos mēs jūs neielaidīsim. Pielāgosim failu authorize.php:

Authorize.php V2 lapa... header("Atrašanās vieta: secretplace.php"); Izeja; ) ) // ja kaut kas bija nepareizi, lietotājs saņems // kļūdas ziņojumu. ?>


) ) ) ?>

Kā atbrīvoties no "cauruma" numura 2? Pieņemsim, ka jums ir vietne, kurā ikviens var reģistrēties, lai publicētu ziņas forumā. Protams, forumā dažiem lietotājiem (administratoriem, moderatoriem) ir vairāk iespēju nekā citiem, piemēram, viņi var izdzēst ziņojumus no citiem lietotājiem. Jūs saglabājat lietotāja piekļuves līmeni sesijā mainīgajā $user_status, kur $user_status = 10 atbilst pilnīgai piekļuvei sistēmai. Uzbrucējam, kurš ierodas vietnē, vienkārši jāreģistrējas parastajā veidā un pēc tam jāpievieno pārlūkprogrammas adreses joslā?user_status=10

. Tātad jūsu forumā ir jauns administrators!

Principā jebkuru skripta mainīgo var iestatīt, izmantojot adreses joslu, vienkārši pievienojot skriptam jautājuma zīmi un mainīgā nosaukumu ar tā vērtību aiz pilnas adreses. Labosim kodu, lai no tā izvairītos: Secretplace.php V2 slepenā vieta.phpmainīgais unset($_SESSION["logged_user"]); // atver sesiju session_start(); /* jūs nevarat vienkārši doties uz šo lapu... ja lietotājvārds nav reģistrēts, tad mēs viņu novirzām uz index.php lapu, lai ievadītu savu pieteikumvārdu un paroli... šeit jūs varat darīt daudz ko, piemēram, atcerieties lietotāja IP un pēc trešajiem mēģinājumiem piekļūt failiem, bloķējiet to. */ if(!isset($_SESSION["logged_user"]))( header("Atrašanās vieta: index.php"); iziet; ) ?>

, jūs atrodaties slepenā lapā!

Rezultāti

Piemēri

?>
Sesijas mehānisms ir diezgan laba PHP valodas iezīme. Sesijas ir vienkāršas un ļoti elastīgas lietošanā. Starp citu, PHP sesijām (pieejama sākot ar versiju 4.0.3) ir viena, maz dokumentēta iezīme - sesijās var glabāt ne tikai mainīgos, bet arī objektus. // Automātiski ievietot SID saitēs. ini_set("session.use_trans_sid", true); session_start(); ?>
Noklikšķiniet šeit!



Noklikšķiniet šeit!!

// Piemērs darbam ar sesijām. session_start(); // Ja tikko apmeklējāt vietni, atiestatiet skaitītāju. if (!isset($_SESSION["count"])) $_SESSION["count"] = 0; //Palieliniet skaitītāju sesijā. $_SESSION["skaits"] = $_SESSION["skaits"] + 1; ?>

Skaitītājs
laiks(-i).
" target="_blank"> Atveriet bērna pārlūkprogrammas logu.
// Vienkāršs piemērs sesiju izmantošanai bez sīkfailiem. session_name("tests"); session_start(); $_SESSION["skaits"] = @$_SESSION["skaits"] + 1; ?>

// Piemērs darbam ar sesijām. session_start(); // Ja tikko apmeklējāt vietni, atiestatiet skaitītāju. if (!isset($_SESSION["count"])) $_SESSION["count"] = 0; //Palieliniet skaitītāju sesijā. $_SESSION["skaits"] = $_SESSION["skaits"] + 1; ?>

Jūs esat atvēris šo lapu pašreizējā pārlūkprogrammas sesijālaiks(-i).
Aizveriet pārlūkprogrammu, lai atiestatītu šo skaitītāju.
?">Noklikšķiniet šeit, lai atsvaidzinātu lapu!

Sveicināti, dārgā kopiena.

Pirmkārt, es vēlos pateikties par ļoti noderīgu resursu. Ne reizi vien šeit esmu atradis daudzas interesantas idejas un praktiskus padomus.

Šī raksta mērķis ir izcelt sesiju izmantošanas nepilnības PHP. Protams, ir PHP dokumentācija un daudz piemēru, un šis raksts nav paredzēts kā pilnīgs ceļvedis. Tas ir paredzēts, lai atklātu dažas nianses darbā ar sesijām un aizsargātu izstrādātājus no nevajadzīgas laika tērēšanas.

Visizplatītākais sesiju izmantošanas piemērs, protams, ir lietotāja autorizācija. Sāksim ar visvienkāršāko ieviešanu, lai pakāpeniski to attīstītu, kad rodas jauni uzdevumi.

(Lai ietaupītu vietu un laiku, mēs ierobežosim savus piemērus tikai ar pašām sesijas funkcijām, nevis veidosim šeit pilnvērtīgu testa aplikāciju ar skaistu klases hierarhiju, visaptverošu kļūdu apstrādi un citām labām lietām).

Funkcija startSession() ( // Ja sesija jau ir sākta, pārtrauciet izpildi un atgriež TRUE // (jāatspējo parametrs session.auto_start php.ini iestatījumu failā - noklusējuma vērtība) if (session_id()) return true; else return session_start(); session_id() // pēc session_start() funkcijas izsaukšanas deleteSession() ( if (session_id()) ( // Ja ir aktīva sesija, izdzēsiet sesijas sīkfailus setcookie(session_name(), session_id(), time(). )-60*60*24 // un iznīcini session_unset( );

Piezīme: Tiek pieņemts, ka lasītājam ir pamatzināšanas par PHP sesijām, tāpēc šeit mēs neaplūkosim session_start() un session_destroy() funkciju darbības principu. Pieteikšanās formas izkārtojuma un lietotāja autentifikācijas uzdevumi nav saistīti ar raksta tēmu, tāpēc arī tos izlaidīsim. Atgādināšu, ka, lai identificētu lietotāju katrā nākamajā pieprasījumā, veiksmīgas pieteikšanās brīdī mums ir jāsaglabā lietotāja identifikators sesijas mainīgajā (piemēram, ar nosaukumu userid), kas būs pieejams visos turpmākajos pieprasījumos sesijas dzīve. Ir arī jāievieš mūsu funkcijas startSession() rezultāta apstrāde. Ja funkcija atgriež FALSE, pārlūkprogrammā parādiet pieteikšanās veidlapu. Ja funkcija atgrieza TRUE un eksistē sesijas mainīgais, kas satur autorizētā lietotāja identifikatoru (mūsu gadījumā - userid), parādiet autorizētā lietotāja lapu (plašāku informāciju par kļūdu apstrādi skatiet papildinājumā, kas datēts ar 2013-06-2013. 07 sadaļā par sesijas mainīgajiem).

Pagaidām viss ir skaidrs. Jautājumi sākas, kad ir jāievieš lietotāja neaktivitātes kontrole (sesijas taimauts), jāļauj vairākiem lietotājiem vienlaikus strādāt vienā pārlūkprogrammā, kā arī jāaizsargā sesijas no nesankcionētas lietošanas. Tas tiks apspriests tālāk.

Lietotāju neaktivitātes uzraudzība, izmantojot iebūvētos PHP rīkus

Pirmais jautājums, kas bieži rodas visu veidu lietotāju konsoļu izstrādātājiem, ir automātiska sesijas pārtraukšana lietotāja neaktivitātes gadījumā. Nav nekā vieglāk, kā to izdarīt, izmantojot PHP iebūvētās iespējas. (Šī opcija nav īpaši uzticama vai elastīga, taču mēs to apsvērsim pilnīguma labad).

Funkcija startSession() ( // Lietotāja neaktivitātes taimauts (sekundēs) $sessionLifetime = 300; if (session_id()) atgriež true; // Iestatiet sīkfaila darbības laiku ini_set("session.cookie_lifetime", $sessionLifetime); // Ja lietotājs ir iestatīts neaktivitātes taimauts, iestatiet sesijas kalpošanas laiku serverī // Piezīme. Ražošanas serverim ir ieteicams iepriekš iestatīt šos parametrus php.ini failā if ($sessionLifetime) ini_set("session.gc_maxlifetime", $sessionLifetime if (session_start(); )) (setcookie(session_name(), session_id(), time()+$sessionLifetime; return true; ) else return false)

Daži precizējumi. Kā zināms, PHP nosaka, kura sesija ir jāuzsāk, pēc pārlūkprogrammas pieprasījuma galvenē nosūtītā sīkfaila nosaukuma. Pārlūkprogramma savukārt saņem šo sīkfailu no servera, kur funkcija session_start() to ievieto. Ja pārlūkprogrammas sīkfaila derīguma termiņš ir beidzies, tas netiks nosūtīts pieprasījumā, kas nozīmē, ka PHP nevarēs noteikt, kuru sesiju sākt, un uzskatīs to par jaunas sesijas izveidi. PHP iestatījumu parametrs session.gc_maxlifetime, kas ir vienāds ar mūsu lietotāja neaktivitātes taimautu, nosaka PHP sesijas ilgumu, un to kontrolē serveris. Sesijas ilguma kontrole darbojas šādi (šeit mēs uzskatām piemēru par sesiju glabāšanu pagaidu failos kā visizplatītāko un noklusējuma opciju PHP).

Kad tiek izveidota jauna sesija, direktorijā, kas PHP iestatījumu parametrā session.save_path iestatīts kā sesijas krātuves direktorijs, tiek izveidots fails ar nosaukumu sess_. , Kur - sesijas identifikators. Pēc tam katrā pieprasījumā jau esošas sesijas palaišanas laikā PHP atjaunina šī faila modifikācijas laiku. Tādējādi katrā nākamajā pieprasījumā PHP, izmantojot starpību starp pašreizējo laiku un sesijas faila pēdējās modifikācijas laiku, var noteikt, vai sesija ir aktīva, vai arī tās darbības laiks jau ir beidzies. (Veco sesijas failu dzēšanas mehānisms ir sīkāk apskatīts nākamajā sadaļā.)

Piezīme:Šeit jāatzīmē, ka parametrs session.gc_maxlifetime attiecas uz visām sesijām viena servera ietvaros (precīzāk, viena galvenā PHP procesa ietvaros). Praksē tas nozīmē, ka, ja serverī darbojas vairākas vietnes un katrai no tām ir savs lietotāja neaktivitātes taimauts, šī parametra iestatīšana vienā no vietnēm novedīs pie tā iestatīšanas citām vietnēm. Tas pats attiecas uz dalītu mitināšanu. Lai izvairītos no šādas situācijas, katrai vietnei tajā pašā serverī tiek izmantoti atsevišķi sesiju direktoriji. Ceļa uz sesiju direktoriju iestatīšana tiek veikta, izmantojot parametru session.save_path php.ini iestatījumu failā vai izsaucot funkciju ini_set(). Pēc tam katras vietnes sesijas tiks saglabātas atsevišķos direktorijos, un vienā no vietnēm iestatītais parametrs session.gc_maxlifetime būs derīgs tikai tās sesijai. Mēs šo gadījumu sīkāk neapskatīsim, jo ​​īpaši tāpēc, ka mums ir elastīgāka iespēja uzraudzīt lietotāju neaktivitāti.

Lietotāja neaktivitātes kontrole, izmantojot sesijas mainīgos

Šķiet, ka iepriekšējā opcija, neskatoties uz visu savu vienkāršību (tikai pāris papildu koda rindiņas), sniedz visu, kas mums nepieciešams. Bet ko tad, ja ne katru pieprasījumu var uzskatīt par lietotāja darbības rezultātu? Piemēram, lapai ir taimeris, kas periodiski veic AJAX pieprasījumu, lai saņemtu atjauninājumus no servera. Šādu pieprasījumu nevar uzskatīt par lietotāja darbību, kas nozīmē, ka automātiska sesijas ilguma pagarināšana šajā gadījumā nav pareiza. Taču mēs zinām, ka PHP automātiski atjaunina sesijas faila modifikācijas laiku ikreiz, kad tiek izsaukta funkcija session_start(), kas nozīmē, ka jebkurš pieprasījums novedīs pie sesijas ilguma pagarinājuma un lietotāja neaktivitātes taimauts nekad nenotiks. Turklāt pēdējā piezīme no iepriekšējās sadaļas par parametra session.gc_maxlifetime sarežģītību dažiem var šķist pārāk mulsinoša un grūti īstenojama.

Lai atrisinātu šo problēmu, atteiksimies no iebūvēto PHP mehānismu izmantošanas un ieviesīsim vairākus jaunus sesijas mainīgos, kas ļaus mums pašiem kontrolēt lietotāja neaktivitātes laiku.

Funkcija startSession($isUserActivity=true) ($sessionLifetime = 300; if (session_id()) atgriež true; // Iestatiet sīkfaila kalpošanas laiku pirms pārlūkprogrammas aizvēršanas (mēs kontrolēsim visu servera pusē) ini_set("session. cookie_lifetime", 0) ; if (! session_start()) return false; $t = time(); if ($sessionLifetime) ( // Ja ir iestatīts lietotāja neaktivitātes taimauts, // pārbaudiet laiku, kas pagājis kopš lietotāja pēdējās darbības // (pēdējā pieprasījuma laiks), kad tika atjaunināts pēdējās aktivitātes sesijas mainīgais) if (isset($_SESSION["lastactivity"]) && $t-$_SESSION["pēdējā darbība"] >= $sessionLifetime) ( // Ja laiks, kas pagājis kopš lietotāja pēdējās darbības, // ir lielāks par neaktivitātes taimautu, kas nozīmē, ka sesija ir beidzies un sesija ir jāpārtrauc pieprasījums radās lietotāja darbības rezultātā, // atjaunināt pēdējās aktivitātes mainīgo ar pašreizējā laika vērtību, // tādējādi pagarinot sesijas laiku par citu sesijas mūža sekundēm, ja ($isUserActivity) $_SESSION["lastactivity"] =; $t; ) ) atgriezt patiesu; )

Apkoposim. Katrā pieprasījumā mēs pārbaudām, vai ir sasniegts taimauts kopš pēdējās lietotāja darbības līdz pašreizējam brīdim, un, ja tas ir sasniegts, iznīcinām sesiju un pārtraucam funkcijas izpildi, atgriežot FALSE. Ja taimauts nav sasniegts un funkcijai tiek nodots parametrs $isUserActivity ar vērtību TRUE, mēs atjauninām lietotāja pēdējās darbības laiku. Viss, kas mums jādara, ir izsaukšanas skriptā noteikt, vai pieprasījums ir lietotāja darbības rezultāts, un, ja nē, izsaukt startSession funkciju ar $isUserActivity parametru, kas iestatīts uz FALSE.

Atjauninājums no 2013-06-07
Funkcijas sessionStart() rezultāta apstrāde

Komentāros tika norādīts, ka FALSE atgriešana nesniedz pilnīgu izpratni par kļūdas cēloni, un tas ir absolūti godīgi. Es šeit nepublicēju detalizētu kļūdu apstrādi (raksta garums jau ir diezgan liels), jo tas nav tieši saistīts ar raksta tēmu. Bet, ņemot vērā komentārus, es paskaidrošu.

Kā redzat, funkcija sessionStart var atgriezt FALSE divos gadījumos. Sesiju nevarēja sākt dažu iekšēju servera kļūdu dēļ (piemēram, nepareizi sesijas iestatījumi php.ini), vai arī ir beidzies sesijas ilgums. Pirmajā gadījumā mums ir jānovirza lietotājs uz lapu ar kļūdu, kurā norādīts, ka serverī ir problēmas, un veidlapa saziņai ar atbalsta dienestu. Otrajā gadījumā mums ir jāpārsūta lietotājs uz pieteikšanās veidlapu un tajā jāparāda atbilstošs ziņojums, ka sesija ir beigusies. Lai to izdarītu, mums ir jāievada kļūdu kodi un jāatgriež atbilstošais kods, nevis FALSE, un izsaukšanas metodē tas jāpārbauda un jārīkojas atbilstoši.

Tagad, pat ja sesija serverī joprojām pastāv, tā tiks iznīcināta, kad tai pirmo reizi piekļūst, ja ir beidzies lietotāja neaktivitātes taimauts. Un tas notiks neatkarīgi no tā, kāds sesijas ilgums ir iestatīts globālajos PHP iestatījumos.

Piezīme: Kas notiek, ja pārlūkprogramma tiek aizvērta un sesijas nosaukuma sīkfails tiek automātiski iznīcināts? Pieprasījums serverim nākamajā pārlūkprogrammas atvēršanas reizē nesaturēs sesijas sīkfailus, un serveris nevarēs atvērt sesiju un pārbaudīt lietotāja neaktivitātes taimautu. Mums tas ir līdzvērtīgs jaunas sesijas izveidei un nekādā veidā neietekmē funkcionalitāti vai drošību. Bet rodas godīgs jautājums - kurš tad iznīcinās veco sesiju, ja līdz šim mēs to esam iznīcinājuši pēc taimauta beigām? Vai arī tas tagad paliks sesiju direktorijā uz visiem laikiem? Lai iztīrītu vecās PHP sesijas, ir mehānisms, ko sauc par atkritumu savākšanu. Tas darbojas laikā, kad serverim tiek nosūtīts nākamais pieprasījums, un notīra visas vecās sesijas, pamatojoties uz sesijas failu pēdējās modifikācijas datumu. Bet atkritumu savākšanas mehānisms nesākas ar katru pieprasījumu serverim. Palaišanas biežumu (vai drīzāk varbūtību) nosaka divi iestatījumu parametri session.gc_probability un session.gc_divisor. Pirmā parametra dalīšanas ar otro rezultāts ir atkritumu savākšanas mehānisma palaišanas varbūtība. Tādējādi, lai sesijas tīrīšanas mehānisms tiktu palaists ar katru pieprasījumu serverim, šie parametri ir jāiestata uz vienādām vērtībām, piemēram, “1”. Šī pieeja garantē tīru sesijas direktoriju, taču acīmredzami ir pārāk dārga serverim. Tāpēc ražošanas sistēmās session.gc_divisor noklusējuma vērtība ir iestatīta uz 1000, kas nozīmē, ka atkritumu savākšanas mehānisms darbosies ar varbūtību 1/1000. Ja eksperimentējat ar šiem iestatījumiem savā php.ini failā, iespējams, pamanīsit, ka iepriekš aprakstītajā gadījumā, kad pārlūkprogramma aizveras un notīra visus sīkfailus, sesiju direktorijā kādu laiku vēl ir palikušas vecās sesijas. Bet tam nevajadzētu jūs uztraukties, jo... kā jau minēts, tas nekādā veidā neietekmē mūsu mehānisma drošību.

Atjauninājums no 2013-06-07

Skriptu iesaldēšanas novēršana sesijas failu bloķēšanas dēļ

Komentāros tika izvirzīts jautājums par vienlaicīgu skriptu iesaldēšanu, jo sesijas fails ir bloķēts (vispārsteidzošākā iespēja ir garā aptauja).

Vispirms es atzīmēju, ka šī problēma nav tieši atkarīga no servera slodzes vai lietotāju skaita. Protams, jo vairāk pieprasījumu, jo lēnāk tiek izpildīti skripti. Bet tā ir netieša atkarība. Problēma parādās tikai vienas sesijas laikā, kad serveris viena lietotāja vārdā saņem vairākus pieprasījumus (piemēram, viens no tiem ir long poll, bet pārējie ir regulāri pieprasījumi). Katrs pieprasījums mēģina piekļūt vienam un tam pašam sesijas failam, un, ja iepriekšējais pieprasījums neatbloķēja failu, nākamais atliks, gaidot.

Lai samazinātu sesijas failu bloķēšanu līdz minimumam, ir ļoti ieteicams aizvērt sesiju, izsaucot funkciju session_write_close() tūlīt pēc visu darbību veikšanas ar sesijas mainīgajiem. Praksē tas nozīmē, ka jums nevajadzētu visu saglabāt sesijas mainīgajos un piekļūt tiem visā skripta izpildes laikā. Un, ja jums ir jāsaglabā daži darba dati sesijas mainīgajos, izlasiet tos nekavējoties, kad sesija sākas, saglabājiet tos lokālajos mainīgajos vēlākai lietošanai un aizveriet sesiju (tas nozīmē, ka sesijas aizvēršana, izmantojot funkciju session_write_close, nevis iznīcināta, izmantojot session_destroy ).

Mūsu piemērā tas nozīmē, ka tūlīt pēc sesijas atvēršanas, tās darbības ilguma un autorizēta lietotāja esamības pārbaudes mums ir jāizlasa un jāsaglabā visi lietojumprogrammai nepieciešamie papildu sesijas mainīgie (ja tādi ir), pēc tam sesija jāaizver, izmantojot zvanu. uz session_write_close() un turpināt skripta izpildi neatkarīgi no tā, vai tā ir gara aptauja vai parasts pieprasījums.

Sesiju aizsardzība pret neatļautu izmantošanu

Iedomāsimies situāciju. Viens no jūsu lietotājiem saņem Trojas zirgu, kas nolaupa pārlūkprogrammas sīkfailus (kurā tiek saglabāta mūsu sesija) un nosūta to uz norādīto e-pastu. Uzbrucējs iegūst sīkfailu un izmanto to, lai maldinātu pieprasījumu mūsu pilnvarotā lietotāja vārdā. Serveris veiksmīgi pieņem un apstrādā šo pieprasījumu tā, it kā tas būtu no autorizēta lietotāja. Ja IP adreses papildu pārbaude netiks ieviesta, šāds uzbrukums novedīs pie veiksmīgas lietotāja konta uzlaušanas ar visām no tā izrietošajām sekām.

Kāpēc tas bija iespējams? Acīmredzot, jo nosaukums un sesijas identifikators vienmēr ir vienādi visā sesijas laikā, un, ja saņemat šos datus, varat viegli nosūtīt pieprasījumus cita lietotāja vārdā (protams, šīs sesijas laikā). Šis varbūt nav visizplatītākais uzbrukuma veids, taču teorētiski tas šķiet diezgan iespējams, īpaši ņemot vērā, ka šādam Trojas zirgam pat nav nepieciešamas administratora tiesības, lai aplaupītu lietotāja pārlūkprogrammas sīkfailus.

Kā jūs varat pasargāt sevi no šāda veida uzbrukumiem? Atkal, protams, ierobežojot sesijas identifikatora kalpošanas laiku un periodiski mainot identifikatoru vienas sesijas laikā. Varam arī mainīt sesijas nosaukumu, pilnībā izdzēšot veco un izveidojot jaunu sesiju, tajā iekopējot visus sesijas mainīgos no vecās. Bet tas neietekmē pieejas būtību, tāpēc vienkāršības labad mēs aprobežosimies ar tikai sesijas identifikatoru.

Ir skaidrs, ka jo īsāks ir sesijas ID kalpošanas laiks, jo mazāk laika uzbrucējam būs nepieciešams iegūt un izmantot sīkfailus, lai viltotu lietotāja pieprasījumu. Ideālā gadījumā katram pieprasījumam būtu jāizmanto jauns identifikators, kas līdz minimumam samazinās iespēju izmantot kāda cita sesiju. Bet mēs apsvērsim vispārējo gadījumu, kad sesijas identifikatora reģenerācijas laiks tiek iestatīts patvaļīgi.

(Mēs izlaidīsim jau apspriesto koda daļu).

Funkcija startSession($isUserActivity=true) (// Sesijas identifikatora ilgums $idLifetime = 60; ... if ($idLifetime) ( // Ja ir iestatīts sesijas identifikatora darbības laiks, // pārbaudiet laiku, kas pagājis kopš sesijas izveidota vai pēdējā reģenerācija // (pēdējā pieprasījuma laiks, kad tika atjaunināts sesijas mainīgais sākuma laiks) if (isset($_SESSION["sākuma laiks"])) (if ($t-$_SESSION["sākuma laiks"] >= $ idLifetime) ( // Laika sesijas identifikators ir beidzies // Ģenerēt jaunu identifikatoru session_regenerate_id(true); $_SESSION["starttime"] = $t ) ) else ( // Mēs nokļūstam šeit, ja sesija ir tikko izveidota // Iestatiet sesijas identifikatora ģenerēšanas laiku uz pašreizējo laiku $_SESSION["sākuma laiks"] = $t ) ) return true ;

Tātad, veidojot jaunu sesiju (kas notiek, kad lietotājs veiksmīgi piesakās), mēs sesijas mainīgajam sākuma laiks, kas mums saglabā sesijas identifikatora pēdējās paaudzes laiku, iestatām vērtību, kas vienāda ar pašreizējo servera laiku. Pēc tam katrā pieprasījumā mēs pārbaudām, vai kopš pēdējās identifikatora paaudzes ir pagājis pietiekami daudz laika (idLifetime), un, ja tā, mēs ģenerējam jaunu. Tādējādi, ja noteiktajā identifikatora darbības laikā uzbrucējam, kurš saņēma autorizētā lietotāja sīkfailu, nav laika to izmantot, serveris uzskatīs viltus pieprasījumu par nesankcionētu, un uzbrucējs tiks novirzīts uz pieteikšanās lapu. .

Piezīme: Jaunais sesijas ID nokļūst pārlūkprogrammas sīkfailā, kad tiek izsaukta funkcija session_regenerate_id(), kas nosūta jauno sīkfailu līdzīgi kā sesijas_start() funkcijai, tāpēc mums pašiem nav jāatjaunina sīkfails.

Ja mēs vēlamies padarīt mūsu sesijas pēc iespējas drošākas, pietiek ar identifikatora dzīves ilgumu iestatīt vienu vai pat noņemt funkciju session_regenerate_id() no iekavām un noņemt visas pārbaudes, kas novedīs pie identifikatora atjaunošanas katrā. pieprasījumu. (Es neesmu pārbaudījis šīs pieejas ietekmi uz veiktspēju, un varu tikai teikt, ka funkcija session_regenerate_id(true) būtībā veic tikai 4 darbības: ģenerē jaunu identifikatoru, izveido galveni ar sesijas sīkfailu, dzēš veco un izveido jauns sesijas fails).

Liriskā novirze: Ja Trojas zirgs izrādīsies tik gudrs, ka nesūtīs sīkfailus uzbrucējam, bet organizēs iepriekš sagatavota viltus pieprasījuma nosūtīšanu uzreiz pēc sīkdatnes saņemšanas, iepriekš aprakstītā metode, visticamāk, nespēs aizsargāt pret tādu. uzbrukums, jo starp brīdi, kad Trojas zirgs saņem sīkfailu un viltus pieprasījuma nosūtīšanu, praktiski nebūs nekādas atšķirības, un pastāv liela varbūtība, ka šajā brīdī sesijas identifikators netiks atjaunots.

Iespēja vienlaikus strādāt vienā pārlūkprogrammā vairāku lietotāju vārdā

Pēdējais uzdevums, ko es vēlētos apsvērt, ir iespēja vairākiem lietotājiem vienlaikus strādāt vienā pārlūkprogrammā. Šī funkcija ir īpaši noderīga testēšanas posmā, kad ir nepieciešams atdarināt lietotāju vienlaicīgu darbu, un ieteicams to darīt savā iecienītākajā pārlūkprogrammā, nevis izmantot visu pieejamo arsenālu vai atvērt vairākus pārlūkprogrammas gadījumus inkognito režīmā. .

Iepriekšējos piemēros mēs skaidri nenorādījām sesijas nosaukumu, tāpēc tika izmantots noklusējuma PHP nosaukums (PHPSESSID). Tas nozīmē, ka visas mūsu līdz šim izveidotās sesijas ir nosūtījušas pārlūkprogrammai sīkfailu ar nosaukumu PHPSESSID. Acīmredzot, ja sīkfaila nosaukums vienmēr ir vienāds, tad vienā pārlūkprogrammā nevar organizēt divas sesijas ar vienādu nosaukumu. Bet, ja mēs katram lietotājam izmantotu savu sesijas nosaukumu, problēma tiktu atrisināta. Darīsim tā.

Funkcija startSession($isUserActivity=true, $prefix=null) (... if (session_id()) atgriež true; // Ja parametros ir nodots lietotāja prefikss, // iestatiet unikālu sesijas nosaukumu, kas ietver šo prefikss, // citādi iestatīt kopējo nosaukumu visiem lietotājiem (piemēram, MYPROJECT) session_name("MYPROJECT".($prefikss ? "_".$prefikss: "") ini_set("session.cookie_lifetime"); if (! session_start()) return false ... )

Tagad atliek tikai pārliecināties, ka izsaucošais skripts funkcijai startSession() nodod unikālu prefiksu katram lietotājam. To var izdarīt, piemēram, katra pieprasījuma GET/POST parametros nosūtot prefiksu vai izmantojot papildu sīkfailu.

Secinājums

Noslēgumā es sniegšu visu mūsu funkciju galīgo kodu darbam ar PHP sesijām, ieskaitot visus iepriekš apspriestos uzdevumus.

Funkcija startSession($isUserActivity=true, $prefix=null) ( $sessionLifetime = 300; $idLifetime = 60; if (session_id()) atgriež true; session_name("MYPROJECT".($prefikss ? "_".$prefikss): "")); ini_set("session.cookie_lifetime", 0). $t-$_SESSION["pēdējā darbība"] >= $sessionLifetime) ( iznīcinātSession(); return false; ) else ( if ($isUserActivity) $_SESSION["pēdējā aktivitāte"] = $t; ) ) if ($idLifetime ) ( if (isset($_SESSION["sākuma laiks"])) (if ($t-$_SESSION["sākuma laiks"] >= $idLifetime) ( session_regenerate_id(true); $_SESSION["sākuma laiks"] = $t; ) ) else ( $_SESSION["sākuma laiks"] = $t; ) ) atgriež funkciju deleteSession() ( if (session_id()) ( session_unset(); setcookie(session_name(), session_id(), time() -60*; 60*24 session_destroy();

Es ceru, ka šis raksts ietaupīs laiku tiem, kuri nekad nav pārāk dziļi iedziļinājušies sesijas mehānismā, un sniegs pietiekamu ieskatu šajā mehānismā tiem, kas tikai sāk iepazīties ar PHP.

Sesijas izveide

Pirmā lieta, kas jums jādara, lai strādātu ar sesijām (ja tās jau ir konfigurējis servera administrators), ir palaist sesijas mehānismu. Ja servera iestatījumos mainīgais session.auto_start ir iestatīts uz "0" (ja session.auto_start=1, tad sesijas tiek sāktas automātiski), tad jebkuram skriptam, kurā jāizmanto sesijas dati, jāsākas ar komandu

Session_start();

Saņemot šādu komandu, serveris izveido jaunu sesiju vai atjauno pašreizējo, pamatojoties uz pieprasījumam nodoto sesijas identifikatoru. Kā tas tiek darīts? PHP tulks meklē mainīgo, kas saglabā sesijas identifikatoru (pēc noklusējuma PHPSESSID), vispirms sīkfailos, pēc tam mainīgajos, kas nodoti, izmantojot POST un GET pieprasījumus. Ja identifikators tiek atrasts, lietotājs tiek uzskatīts par identificētu, tiek aizstāti visi URL un iestatīti sīkfaili. Pretējā gadījumā lietotājs tiek uzskatīts par jaunu, viņam tiek ģenerēts jauns unikālais identifikators, pēc tam tiek aizstāts URL un iestatīti sīkfaili.

Komanda session_start() ir jāizsauc visos skriptos, kuros jāizmanto sesijas mainīgie, un pirms datu izvadīšanas pārlūkprogrammā. Tas ir saistīts ar faktu, ka sīkfaili tiek iestatīti tikai pirms informācijas parādīšanas ekrānā.

Pašreizējās sesijas identifikatoru var iegūt, izmantojot funkciju session_id().

Skaidrības labad varat iestatīt sesijas nosaukumu, izmantojot funkciju sesijas_nosaukums([sesijas_nosaukums]).

Tas jādara pirms sesijas inicializācijas. Pašreizējās sesijas nosaukumu var iegūt, izmantojot to pašu funkciju, izsauktu bez parametriem: session_name();

Piemērs. Sesijas izveide

Pārdēvēsim savu index.html failu tā, lai PHP skripti tiktu apstrādāti, piemēram, par Index.php, izveidosim sesiju un paskatīsimies, kādu identifikatoru un nosaukumu tas saņems.

session_start();
// izveidot jaunu sesiju vai
// atjaunot pašreizējo echo session_id();
?>

Mana mājas lapa
... // mājas lapa

echo session_name();
// parāda pašreizējās sesijas nosaukumu.
// Šajā gadījumā tas ir PHPSESSID
?>

Ja jūs darāt to pašu ar failu authorize.php, tad izvades mainīgo vērtības (sesijas ID un tā nosaukums) būs vienādas, ja dodaties uz to no index.php un vispirms neaizverat pārlūkprogrammas logu ( tad mainīsies sesijas identifikators).

Sesijas mainīgo reģistrēšana

Tomēr pats identifikators un sesijas nosaukums mums maz noder mūsu problēmu risināšanā. Sesijas laikā mēs vēlamies pārsūtīt un saglabāt savus mainīgos (piemēram, pieteikšanās vārdu un paroli).

Lai to panāktu, jums vienkārši jāreģistrē mainīgie:

Session_register(mainīgā_nosaukums1,
mainīgais_nosaukums2, ...);

Ņemiet vērā, ka tiek reģistrētas nevis vērtības, bet gan mainīgo nosaukumi. Pietiek vienreiz reģistrēt mainīgo jebkurā lapā, kurā tiek izmantotas sesijas. Mainīgo nosaukumi tiek nodoti session_register() bez $ zīmes.

Visi šādā veidā reģistrētie mainīgie kļūst globāli (t.i., pieejami no jebkuras lapas) noteiktā darba sesijas laikā ar vietni.

Varat arī reģistrēt mainīgo, vienkārši ierakstot tā vērtību asociatīvajā masīvā $_SESSION, t.i. uzrakstījis

$_SESSION["mainīgā_nosaukums"] =
"mainīgā_vērtība";

Šajā masīvā tiek glabāti visi reģistrētie (t.i., globālie) sesijas mainīgie.

Šādiem mainīgajiem var piekļūt, izmantojot masīvu $_SESSION["mainīgā_nosaukums"] (vai $HTTP_SESSION_VARS["mainīgā_nosaukums"] PHP 4.0.6 un vecākām versijām).

Ja PHP iestatījumos ir iespējota opcija register_globals, tad sesijas mainīgajiem var piekļūt arī kā parastiem mainīgajiem, piemēram: $mainīgā_nosaukums.

Ja register_globals=off (atspējots), tad nevar izmantot session_register(), lai reģistrētu mainīgos, kas nodoti ar POST vai GET metodēm, t.i. tas vienkārši nedarbojas. Kopumā nav ieteicams vienlaikus izmantot abas mainīgo reģistrācijas metodes, $_SESSION un session_register().

Piemērs 12.3. Mainīgo reģistrēšana
Reģistrēsim autorizācijas lapā lietotāja ievadīto pieteikumvārdu un paroli.

session_start();
// izveidot jaunu sesiju vai
// atjaunot pašreizējo if (!isset($_GET["go"]))(
atbalss"


Pieslēgties:
Parole: name=passwd>

";
)cits (
$_SESSION["pieteikšanās"]=$_GET["pieteikšanās"];
// reģistrēt pieteikšanās mainīgo
$_SESSION["passwd"]=$_GET["passwd"];
// reģistrēt passwd mainīgo
// tagad pieteikšanās vārds un parole ir globāli
// šīs sesijas mainīgie
if ($_GET["pieteikšanās"]=="bedre" &&
$_GET["passwd"]=="123") (
Header("Atrašanās vieta: secret_info.php");
// novirzīt uz lapu
// secret_info.php
)else echo "Nederīga ievade,
mēģini vēlreiz
";
}
print_r($_SESIJA);
?>

Tagad, nokļuvuši secret_info.php lapā un jebkurā citā vietnes lapā, mēs varēsim strādāt ar lietotāja ievadīto lietotājvārdu un paroli, kas tiks saglabāti $_SESSION masīvā. Tādējādi, ja maināt slepenās lapas kodu (ņemiet vērā, ka mēs to pārdēvējām secret_info.php) šādi:

session_start();
// izveidot jaunu sesiju vai
// parādīt visus sesijas mainīgos
?>

Slepena informācija

Šeit es vēlos dalīties noslēpumos ar savu draugu Petju.



Pēc tam pārlūkprogrammā slepenajā lapā iegūsim šādu informāciju:

Masīvs (=> bedre => 123)
Šeit es vēlos dalīties noslēpumos ar savu draugu Petju.

Rezultātā mēs iegūstam vietnē authorize.php reģistrēto mainīgo sarakstu un faktiski pašu slepeno lapu.

Ko tas mums dod? Pieņemsim, ka hakeris vēlas izlasīt Vasjas un Petjas noslēpumus. Un viņš kaut kā uzzināja slepenās lapas (vai lapu) nosaukumu.

Pēc tam viņš var mēģināt vienkārši ievadīt viņas adresi pārlūkprogrammas rindā, apejot autorizācijas (paroles ievadīšanas) lapu. Lai izvairītos no šādas iespiešanās mūsu noslēpumos, slepeno lapu kodam jāpievieno tikai dažas rindiņas:

session_start();
// izveidot jaunu sesiju vai
// atjaunot pašreizējo print_r($_SESSION);
// parādīt visus sesijas mainīgossif (!($_SESSION["login"]=="bedre" &&
$_SESSION["passwd"]==123))
// pārbaudiet pareizību
// pieslēgšanās parole
Header ("Atrašanās vieta: authorize.php");
// ja ir kļūda, tad novirzīt uz
// pieteikšanās lapa
?>

Slepena informācija
... // atrodas šeit
//slepena informācija :)

Sesijas mainīgo noņemšana

Papildus iespējai reģistrēt sesijas mainīgos (tas ir, padarīt tos globālus visā sesijā), ir arī noderīgi, ja ir iespēja dzēst šādus mainīgos un sesiju kopumā.

Funkcija session_unregister(mainīgā_nosaukums) noņem globālo mainīgo no pašreizējās sesijas (tas ir, noņem to no reģistrēto mainīgo saraksta).

Ja reģistrācija tika veikta, izmantojot $_SESSION ($HTTP_SESSION_VARS PHP 4.0.6 un vecākām versijām), tad tiek izmantota unset() valodas konstrukcija. Tas neatgriež nekādu vērtību, bet vienkārši iznīcina norādītos mainīgos.

Kur tas var noderēt? Piemēram, lai iznīcinātu datus par apmeklētāju (jo īpaši pieteikumvārdu un paroli) pēc tam, kad viņš atstāj slepeno lapu. Ja ir saglabāts pareizais pieteikšanās vārds un parole un pārlūkprogrammas logs pēc vietnes apmeklējuma netiek aizvērts, tad jebkurš cits šī datora lietotājs varēs lasīt privāto informāciju.

1. piemērs. Sesijas mainīgo iznīcināšana

Lai piekļūtu galvenajai lapai, failam secret_info.php pievienojiet rindiņu:

// ... php kods
?>

Slepena informācija
... // atrodas šeit
// slepena informācija :)
Uz galveno

Vietnē Index.php mēs izdzēsīsim iepriekš ievadīto pieteikumvārdu un paroli:

session_start();
session_unregister("passwd");
// iznīcināt paroli unset($_SESSION["pieteikšanās"]);
// iznīcināt loginprint_r($_SESSION);
// parādīt globālos sesijas mainīgos
?>

Mana mājas lapa
... // mājas lapa

Tagad, lai nokļūtu slepenajā lapā, jums vēlreiz būs jāievada savs pieteikumvārds un parole.

Lai atiestatītu visu sesijas mainīgo vērtības, varat izmantot funkciju session_unset();

Jūs varat iznīcināt visu pašreizējo sesiju, izmantojot komandu session_destroy();

Tas neatiestata globālos sesijas mainīgos vai neizdzēš sīkfailus, bet gan iznīcina visus ar pašreizējo sesiju saistītos datus.

session_start(); // inicializēt sesiju $test = "Sesijas mainīgais";
$_SESSION["tests"]= $tests;
// reģistrēt mainīgo $test.
// ja register_globals=on,
// tad varam izmantot
// session_register("tests");

print_r($_SESIJA);
// parādīt visus globālos mainīgos
echo session_id();
// parāda sesijas ID
atbalss"


";
session_unset();
// iznīcināt visas globālās
// sesijas mainīgiesprint_r($_SESSION);
echo session_id();
atbalss"
";
session_destroy(); // iznīcināt sesiju print_r($_SESSION);
echo session_id();
?>

Šī skripta rezultātā tiks parādītas trīs rindas: pirmajā - masīvs ar testa elementu un tā vērtību, kā arī sesijas identifikators, otrajā - tukšs masīvs un sesijas identifikators, trešajā - tukšs masīvs. Tādējādi ir skaidrs, ka pēc sesijas iznīcināšanas tiek iznīcināts arī tās identifikators, un mēs vairs nevaram reģistrēt mainīgos vai vispārīgi veikt nekādas darbības ar sesiju.

Sesijas patiesībā ir ļoti vienkāršas. Jums tikai jāsaprot, kāpēc tie ir vajadzīgi un kā tie darbojas. Vispirms atbildēsim uz pirmo jautājumu.
Iespējams, zināt, ka tīmekļa serveris neuztur pastāvīgu savienojumu ar klientu, un katrs pieprasījums tiek apstrādāts kā jauns, bez savienojuma ar iepriekšējiem.

Tas nozīmē, ka starp atsevišķu lapu skatījumiem nevar ne izsekot pieprasījumus no viena un tā paša apmeklētāja, ne arī saglabāt viņam mainīgos. Lai atrisinātu šīs divas problēmas, tika izgudrotas sesijas.
Īsumā, sesijas ir mehānisms, kas ļauj unikāli identificēt pārlūkprogrammu un serverī izveido failu šai pārlūkprogrammai, kurā tiek glabāti sesijas mainīgie.

Sīki neaprakstīšu šāda mehānisma nepieciešamību. Tie ir tādi gadījumi kā iepirkumu grozs interneta veikalā, autorizācija, kā arī ne gluži triviālas problēmas, piemēram, vietnes interaktīvo daļu aizsardzība no surogātpasta.

Principā ir diezgan viegli izveidot savu sesiju analogu, kas nav tik funkcionāls kā PHP iebūvētais, bet pēc būtības ir līdzīgs. Pamatojoties uz sīkfailiem un datu bāzi.

Pieprasot skriptu, mēs skatāmies, vai nav ienācis sīkfails ar noteiktu nosaukumu. Ja sīkfailu nav, iestatiet tos un ierakstiet datu bāzē jaunu rindu ar lietotāja datiem. Ja ir sīkdatnes, tad nolasām datus no datu bāzes. Ar citu pieprasījumu mēs izdzēšam vecos ierakstus no datu bāzes, un tagad mums ir gatavs sesijas mehānisms. Tas nemaz nav grūti. Bet ir dažas nianses, kuru dēļ ir vēlams izmantot iebūvēto sesijas mehānismu.

Pirmkārt, jums kaut kā jāidentificē pārlūkprogramma. Lai to izdarītu, jums ir jāpiešķir tai unikāls identifikators un jālūdz to pārsūtīt ar katru pieprasījumu. Man ir neērti atzīties, bet, kad es pirmo reizi uzzināju par sesijām, es domāju, ka tas ir kaut kāds īpašs mehānisms, kāds jauns saziņas veids starp pārlūkprogrammu un serveri - “sesijas”. Ka sesijas identifikators tiek pārsūtīts kādā īpašā veidā. Bet vilšanās bija smaga...

Sesijās tiek izmantotas standarta, labi zināmas datu pārsūtīšanas metodes. Patiesībā citu vienkārši nav.
Identifikators ir parasts mainīgais. Pēc noklusējuma tā nosaukums ir PHPSESSID.
PHP uzdevums ir nosūtīt to pārlūkprogrammai, lai tā to atgrieztu ar nākamo pieprasījumu. No jau minētās FAQ sadaļas ir skaidrs, ka mainīgo var nodot tikai divos veidos: sīkfailos vai ar POST/GET pieprasījumu.
PHP izmanto abas opcijas.

Par to atbild divi php.ini iestatījumi:

session.use_cookies - ja vienāds ar 1, tad PHP nodod identifikatoru sīkfailiem, ja 0, tad nē.
session.use_trans_sid ja vienāds ar 1, tad PHP to pārsūta, pievienojot URL un formām, ja 0, tad nē.

Šos un citus sesijas parametrus var mainīt tāpat kā citus PHP iestatījumus - failā php.ini, kā arī izmantojot komandu ini_set() vai tīmekļa servera konfigurācijas failos

Ja ir iespējots tikai pirmais, tad sesijas sākumā (katrs zvans session_start()) klientam tiek iestatīti sīkfaili. Pārlūkprogramma pareizi atgriež šo sīkfailu ar katru nākamo pieprasījumu, un PHP ir sesijas identifikators. Problēmas sākas, ja pārlūkprogramma neatgriež sīkfailus. Šajā gadījumā, nesaņemot sīkfailus ar identifikatoru, PHP vienmēr sāks jaunu sesiju, un mehānisms nedarbosies.

Ja ir iespējots tikai otrais, sīkfaili netiek iestatīti. Un tas notiek, kā dēļ patiesībā ir vērts izmantot iebūvēto sesijas mehānismu. Kad skripts ir paveicis savu darbu un lapa ir pilnībā izveidota, PHP to visu skenē un katrai saitei un katrai veidlapai pievieno sesijas identifikatoru. Tas izskatās apmēram šādi:

Rādītājs

kļūst par

Rādītājs

un veidlapām tiek pievienots slēpts lauks

Teorētiski mūsu paštaisītajās sesijās par sīkfailiem un datubāzi varat manuāli piešķirt ID pārsūtīšanu visām saitēm – un tad mūsu pašu sesijas darbosies neatkarīgi no sīkfailiem. Bet vai jūs piekrītat — patīkamāk, ja to dara kāds cits? ;-)

Pēc noklusējuma abas opcijas ir iespējotas jaunākajās PHP versijās. Kā PHP tiek galā ar to? Pavārs vienmēr tiek izstādīts. Un saites tiek automātiski pabeigtas tikai tad, ja PHP neatklāj sīkfailus ar sesijas identifikatoru. Kad lietotājs pirmo reizi apmeklē vietni šīs sesijas laikā, tiek iestatīti sīkfaili un tiek pabeigtas saites. Nākamajā pieprasījumā, ja sīkfaili tiek atbalstīti, PHP redz sīkfailus un pārtrauc saišu aizpildīšanu. Ja sīkfaili nedarbojas, PHP turpina pareizi pievienot saitēm id, un sesija netiek zaudēta.
Lietotāji, kuriem ir iespējoti sīkfaili, garo saiti ar ID redzēs tikai vienu reizi.

ID pārsūtīšana ir pabeigta. Tagad atliek tikai saistīt datu failu ar to servera pusē. PHP to izdarīs mūsu vietā. Vienkārši rakstiet:

session_start();
$_SESSION [ "test" ]= "Sveika pasaule!" ;

Un PHP ierakstīs testa mainīgo failā, kas saistīts ar šo sesiju.

Šeit ir ļoti svarīga piezīme.

Masīvs $_SESIJA- īpašs.
Faktiski tajā ir mainīgie, kurus mēs vēlamies padarīt pieejamus dažādos skriptos.
Lai sesijā ievietotu mainīgo, vienkārši piešķiriet to masīva elementam $_SESSION.
Lai iegūtu tā vērtību, vienkārši piekļūstiet tam pašam elementam. Piemērs būs zemāk.

PHP nodarbojas arī ar atkritumu savākšanu – novecojušo failu dzēšanu. Kā arī datu kodēšana un kaudze citu nepieciešamo lietu. Šīs aprūpes rezultātā darbs ar sesijām ir ļoti vienkāršs.
Šeit mēs faktiski nonākam pie piemēra, kā darbojas sesijas.
Ļoti mazs piemērs:

session_start();

atbalss "Jūs esat atjauninājis šo lapu". $_SESSION["skaitītājs"]++. "vienreiz.";
atbalss"
Atjaunināt" ;
?>

Mēs pārbaudām, vai mums ir skaitītāja mainīgais sesijā, ja nav, tad mēs izveidojam to ar vērtību 0 un pēc tam parādām tā vērtību un palielinām to par vienu. Palielinātā vērtība tiks ierakstīta sesijā, un nākamreiz, kad skripts tiks izsaukts, mainīgā vērtība būs 1 utt. Viss ir ļoti vienkārši.

Lai piekļūtu sesijas mainīgajiem jebkurā vietnes lapā, jums ir jāieraksta TIKAI VIENA (!) rindiņa KATRA faila, kurā mums ir nepieciešamas sesijas, pašā sākumā:

session_start();

session_start();
if ($_SESSION [ "autorizēts"]<> 1 ) {
header("Atrašanās vieta: /auth.php" );
Izeja;
}

Mainīgo noņemšana no sesijas. Ja jums ir register_globals=off , tad vienkārši rakstiet

unset($_SESSION [ "var"]);

Ja nē, tad tuvumā ar to jums jāraksta:

session_unregister("var");

Ir ļoti svarīgi saprast, kādiem nolūkiem sesijas ir jāizmanto un kam tās nevajadzētu.

Pirmkārt, atcerieties, ka sesijas var izmantot tikai tad, kad lietotājam tās ir vajadzīgas, nevis lai viņu traucētu. Galu galā viņš jebkurā laikā var atbrīvoties no identifikatora!
Teiksim, pārbaudot, vai veidlapu aizpilda cilvēks, nevis skripts, lietotājs pats ir ieinteresēts, lai sesija darbotos – pretējā gadījumā viņš nevarēs iesniegt formu! Taču sesija vairs nav piemērota skripta pieprasījumu skaita ierobežošanai — ļaunprātīgs skripts vienkārši neatgriezīs identifikatoru.

Otrkārt. Ir svarīgi skaidri saprast, ka sesija ir darba sesija ar vietni, kā cilvēks to saprot. Atnācu, strādāju, aizvēru pārlūkprogrammu - sesija beidzās. Kā filmas seanss. Ja vēlaties redzēt citu, iegādājieties jaunu biļeti. Sāciet jaunu sesiju. Tam ir arī tehnisks skaidrojums. Tiek garantēts, ka sesijas mehānisms darbosies tikai līdz pārlūkprogrammas aizvēršanai. Galu galā sīkdatnes klientam var nedarboties, un šajā gadījumā, protams, visas saites, kas papildinātas ar identifikatoru, pazudīs, to aizverot.

Tiesa, sesija var pazust, neaizverot pārlūkprogrammu. Šajā rakstā aplūkoto ierobežojumu dēļ sesijas mehānisms nevar noteikt brīdi, kad lietotājs aizvēra pārlūkprogrammu. Šim nolūkam tiek izmantots taimauts - iepriekš noteikts laiks, pēc kura mēs uzskatām, ka lietotājs ir atstājis vietni. Pēc noklusējuma šis iestatījums ir 24 minūtes.

Ja vēlaties saglabāt lietotāja informāciju ilgāku laiku, izmantojiet sīkdatnes un, ja nepieciešams, datu bāzi serverī. Jo īpaši šādi darbojas visas populārās autorizācijas sistēmas:

Identificējot lietotāju, sākas sesija un tajā tiek pārraidīta autorizācijas zīme.
- Ja jums ir nepieciešams “atcerēties” lietotāju, tiek iestatīts sīkfails, lai viņu identificētu.
- Nākamreiz, kad lietotājs apmeklē vietni, lai pieteiktos, viņam vai nu jāievada parole, vai arī sistēma pati to atpazīst, izmantojot iepriekš iestatītās sīkdatnes, un sākas sesija. Jauna sesija, nevis turpināt veco.

Treškārt, jums nevajadzētu sākt sesijas bez izšķirības visiem, kas ienāk vietnē. Tas radīs pilnīgi nevajadzīgu slogu. Neizmantojiet sesijas sīkumiem - piemēram, skaitītājos. Spylog izsauktās sesijas, protams, tiek skaitītas, pamatojoties uz pieteikšanās statistiku, nevis izmantojot PHP līdzīgu sesijas mehānismu.

Turklāt pieņemsim meklētājprogrammu, kas indeksē jūsu vietni. Ja meklēšanas robots neatbalsta sīkdatnes, tad PHP pēc noklusējuma piegādās saitēm PHPSESSID, kas meklētājam var nebūt īpaši patīkami, kas, pēc baumām, tik un tā nedod priekšroku dinamiskām saitēm, bet šeit kopumā - a jauna adrese katru reizi, kad apmeklējat!

Ja sesijas tiek izmantotas, lai ierobežotu piekļuvi slēgtai vietnes sadaļai, tad viss ir tikai meklētājprogramma, un to nevajadzētu indeksēt. Ja viena un tā pati lapa ir jārāda gan autorizētiem, gan neautorizētiem lietotājiem, tad palīdzēs šis triks – sāciet sesiju tikai tiem, kas ievadījuši paroli, vai tiem, kuri jau ir sākuši sesiju.

Lai to izdarītu, dodieties uz katras lapas sākumu, nevis tikai session_start() mēs rakstām:

if (isset($_REQUEST [ sesijas_nosaukums ()])) session_start ();

Tādējādi mēs sākam sesiju tikai tiem, kas nosūtīja identifikatoru.
Attiecīgi tas ir jānosūta lietotājam pirmo reizi – autorizācijas brīdī.

Ja vārds un identitāte ir pareizi, mēs rakstām session_start() !

Visbiežāk sastopamās kļūdas, ko PHP rada, mēģinot strādāt ar sesijām, ir šādas:
Divas no tām

Brīdinājums: nevar nosūtīt sesijas sīkfailu — galvenes jau ir nosūtītas
Brīdinājums: nevar nosūtīt sesijas kešatmiņas ierobežotāju — galvenes jau ir nosūtītas

ko izraisa tas pats iemesls, risinājums ir aprakstīts šajā pavedienā

Brīdinājums: open(/tmp\sess_SID, O_RDWR) neizdevās: rindiņas numurā full_script_path nav šāda faila vai direktorija (2).

Iepriekš viņa izskatījās

Brīdinājums: neizdevās ierakstīt sesijas datus (failus). Lūdzu, pārbaudiet, vai pašreizējais session.save_path iestatījums ir pareizs (/tmp) ,

ja tiek tulkots no angļu valodas, tas sīki izskaidro problēmu: nav pieejams ceļš uz php.ini norādīto direktoriju, kurā tiek rakstīti sesijas faili. Šo kļūdu ir visvieglāk novērst. Vienkārši reģistrējiet direktoriju, kas pastāv un ir rakstāms, piemēram,

session.save_path = c:\windows\temp

Un neaizmirstiet pēc tam restartēt Apache.

Kā izrādās, cilvēka intelektam nav robežu, un tāpēc esmu spiests paskaidrot:
ziņojums par trešo kļūdu (direktoriju nevar atrast) NEizbēgami novedīs pie pirmo divu parādīšanās, jo kļūdas ziņojums tiek izvadīts pārlūkprogrammā un galvenes pēc tam, kad to nevar izmantot. Tāpēc nesteidzieties meklēt priekšlaicīgu secinājumu, bet vispirms pierakstiet pareizo ceļu!

Nākamā izplatītākā problēma, strādājot ar sesijām, ir register_globals lielais mantojums. NEDODIET skripta mainīgo nosaukumus, kas atbilst masīva $_SESSION indeksiem!

Ar register_globals=on vērtības pārrakstīs viena otru un jūs apmulsīsit.

Ja tas nedarbojas, bet netiek parādīts neviens ziņojums, pievienojiet divas rindiņas pašā skripta sākumā, kas atbild par VISU kļūdu rādīšanu ekrānā - ir pilnīgi iespējams, ka ir kļūdas, bet jūs tās vienkārši neredzat.

ini_set("displeja_kļūdas" , 1 );
kļūdu_ziņošana (E_ALL);

vai skatiet kļūdas error_log. Kopumā kļūdas ziņojumu parādīšanas tēma ir ārpus šī raksta darbības jomas, tāpēc pārliecinieties, ka varat tos vismaz redzēt. Nedaudz vairāk par kļūdu atrašanu varat lasīt šajā sadaļā.

Ja esat pārliecināts, ka kļūdu nav, bet sniegtais piemērs tik un tā nedarbojas, iespējams, PHP neiespējo ID nodošanu caur URL, un sīkdatnes nez kāpēc nedarbojas.
Skatiet, kas notiek ar jūsu sīkfailiem.

Parasti, ja jūsu sesijas nedarbojas, vispirms mēģiniet manuāli nodot sesijas identifikatoru, tas ir, izveidojiet saiti un piešķiriet tai identifikatoru:

session_start();
if (!isset($_SESSION [ "skaitītājs" ])) $_SESSION [ "skaitītājs" ]= 0 ;
atbalss "Jūs esat atjauninājis šo lapu". $_SESSION["skaitītājs"]++. "vienu reizi.

Atjaunināt" ;
?>

Šajā gadījumā jums ir jāpārliecinās, ka nav iespējota direktīva session.use_only_cookies, kas neļauj PHP pieņemt sesijas identifikatoru, ja tas tika nodots caur URL.

Ja šis piemērs nedarbojas, tad problēma ir niecīga drukas kļūdas(puse no "problēmām" ar sesijām rodas no nepareizi uzrakstīta mainīgā nosaukuma) vai pārāk vecā PHP versijā: sesiju atbalsts parādījās 4.0 versijā, un masīvs $_SESIJA- 4.1 (pirms tam tas tika izmantots $HTTP_SESSION_VARS).

Ja tas darbojas, tad problēma ir sīkfailos. Pārraugiet, kādus sīkfailus serveris iestata pārlūkprogrammai un vai pārlūkprogramma tos atgriež. Ir ļoti noderīgi meklēt, aplūkojot HTTP galveņu apmaiņu starp pārlūkprogrammu un serveri.

Sīkdatņu darbības skaidrojums neietilpst jau tā pārāk garajā tekstā, taču vismaz pārliecinieties, ka serveris nosūta sīkfailus ar identifikatoru un pārlūkprogramma tos atgriež. Un tajā pašā laikā identifikatori sakrīt viens ar otru =)
Sīkfailu iestatīšanai vajadzētu izskatīties šādi

Set-Cookie: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6;

Set-Cookie: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6; ceļš=/

(ja pieprasāt skriptu nevis no saknes direktorija)
Servera atbildei vajadzētu izskatīties šādi

Sīkfails: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6

Sīkfails: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6; b=b

ja pārlūkprogramma atgriež sīkfailus, kas nav sesijas ID.

Ja piemērs no šejienes darbojas, bet jūsu kods nedarbojas, tad problēma acīmredzami nav sesijās, bet gan algoritmā. Atrodiet, kur pazaudējāt mainīgo, soli pa solim pārsūtiet piemēru no šejienes un atkļūdojiet skriptu.

Cita problēma var rasties, ja izmantojat galvenes novirzīšanu vai JavaScript navigāciju.
Fakts ir tāds, ka PHP automātiski pievieno sesijas identifikatoru tikai tādām saitēm kā
, bet to nedara galvenēm, JavaScript un meta tagiem.

Tāpēc identifikators ir jāpievieno manuāli, piemēram, šādi:

header("Atrašanās vieta: /script.php?" . session_name(). "=" . session_id());

Turklāt ļoti reta problēma, un nav pilnīgi skaidrs, no kurienes tā nāk, ir tā, ka iestatījuma session.save_handler vērtība atšķiras no failiem. Ja tas tā nav, izlabojiet to.

  • Papildus sīkfailiem sesijas mehānisms nosūta arī galvenes, kas aizliedz lapas saglabāšanu kešatmiņā (tas pats kešatmiņas ierobežotājs). Attiecībā uz html tas ir pareizi un nepieciešams. Bet, mēģinot nosūtīt failu, izmantojot skriptu, kas pārbauda autorizāciju, Internet Explorer atsakās to lejupielādēt. Tas ir šī titula dēļ. Zvaniet
    session_cache_limiter("privāts");
    pirms sesijas sākuma ir jāatrisina problēma.
  • Lai cik dīvaini tas neliktos, bet masīvā $_SESIJA Jūs nevarat izmantot ciparu indeksus - $_SESSION [1], $_SESSION [ "10"]- sesijas nedarbosies.
  • Kaut kur starp versijām 4.2 un 5.0 nebija iespējams iestatīt session.use_trans_sid, izmantojot ini_set(). Sākot no 5.0 tas jau atkal ir iespējams.
  • Pirms versijas 4.3.3 sīkfailiem PHP nosūtīja sīkfailus tikai tad, ja pieprasījumā nebija identifikatora, kad sesija sākās. Tagad sīkfaili tiek nosūtīti katrā zvanā session_start

    Ja jums ir kādi citi jautājumi vai kaut kas nav skaidrs - laipni lūdzam mūsu



Tops