Uhamisho wa data ya Php kati ya vipindi. Kazi za kupata vipindi. Mifano ya kazi ya kikao

Kazi za Ufikiaji wa Kikao

Usaidizi wa kipindi katika PHP ni njia ya kuhifadhi data mahususi katika ufikiaji unaofuatana. Hii inafanya uwezekano wa kuunda programu maalum zaidi na kuongeza mvuto wa tovuti yako.

Ikiwa unafahamu kudumisha vipindi na PHPLIB, utagundua kuwa masuala fulani ni sawa na kudumisha vipindi katika PHP.

Mtu anayetembelea tovuti yako amepewa kitambulisho cha kipekee, kinachojulikana kama kitambulisho cha kipindi. Inahifadhiwa kwenye kidakuzi upande wa mtumiaji au hudungwa kwenye URL.

Usaidizi wa kipindi hukupa uwezo wa kusajili idadi kiholela ya vigezo na kuzihifadhi kati ya utekelezaji wa hoja. Mtumiaji anapoingia kwenye tovuti yako, PHP itakuwa kiotomatiki (ikiwa session.auto_start imewekwa kuwa 1) au kwa ombi lako (kwa uwazi - kupitia session_start() au kwa njia isiyo wazi - kupitia session_register()) angalia ikiwa kitambulisho maalum cha kikao kilitumwa pamoja na ombi. Ikiwa ndivyo, mazingira ya awali yanaundwa upya.

Vigezo vyote vilivyosajiliwa vinasasishwa baada ya ombi kuisha. Vigeu vilivyosajiliwa ambavyo havijabainishwa vinawekwa alama kama ambavyo havijafafanuliwa. Kwa maombi yanayofuata hayaamuliwi na moduli ya kipindi isipokuwa mtumiaji atayafafanua baadaye.

Kutumia $_SESSION (au $HTTP_SESSION_VARS katika PHP 4.0.6 au matoleo ya awali) kunapendekezwa kwa sababu za usalama na usomaji wa msimbo. Ikiwa kuna vibadala $_SESSION au $HTTP_SESSION_VARS, hakuna haja ya kutumia vitendaji vya session_register()/session_unregister()/session_is_registered(). Watumiaji wanaweza kufikia utofauti wa kipindi kama kigezo cha kawaida.

Mfano wa 2: Kubatilisha kusajili kigezo kwa kutumia $_SESSION

session_start();
// Tumia $HTTP_SESSION_VARS na PHP 4.0.6 au chini
haijawekwa($_SESSION [ "hesabu" ]);
?>
Tahadhari!

Ikiwa unatumia $HTTP_SESSION_VARS / $_SESSION na register_globals imezimwa, usitumie session_register() , kikao_kimesajiliwa() Na session_unregister() .

Kigezo cha URL

Mtindo wa kikao unasaidia njia zote mbili. Vidakuzi ni bora, lakini kwa sababu si salama (wateja wanaweza wasikubali), hatuwezi kutegemea. Njia ya pili hupachika kitambulisho cha kipindi moja kwa moja kwenye URL.

PHP ina uwezo wa kufanya hivi kwa uwazi wakati imeundwa na --enable-trans-sid chaguo. Ukiwezesha chaguo hili, URI za jamaa zitabadilika ili kujumuisha kitambulisho cha kipindi kiotomatiki. Vinginevyo, unaweza kutumia SID mara kwa mara, ambayo inafafanuliwa ikiwa mteja hajatuma kidakuzi kinacholingana. SID ni ya fomu session_name=session_id au mfuatano usio na kitu.

Kumbuka: Maagizo ya arg_separator.output php.ini hukuruhusu utaalam wa kitenganishi cha hoja.

Mfano ufuatao unaonyesha jinsi ya kusajili kigezo na jinsi ya kuwasiliana kwa usahihi na ukurasa mwingine kwa kutumia SID.

Mfano 5: Kuhesabu idadi ya kuingia kwa mtumiaji binafsi

ikiwa (! kipindi_kimesajiliwa ("hesabu")) (
session_register("hesabu");
$hesabu = 1;
) mwingine (
$hesabu++;
}
?>

Habari mgeni, umeona ukurasa huunyakati.

Ili kuendelea, ">bofya
hapa.

SID?> haihitajiki ikiwa --enable-trans-sid ilitumiwa wakati wa kuandaa PHP.

Kumbuka: Inachukuliwa kuwa URL zisizo za uhusiano huelekeza kwenye tovuti za nje na kwa hivyo haziambatishi SID, kwa kuwa kuna hatari ya kuvuja maelezo ya SID kwenye seva nyingine.

Ili kutekeleza uhifadhi wa hifadhidata au njia nyingine utahitaji kutumia session_set_save_handler() kuunda seti ya vitendaji vya uhifadhi wa kiwango cha mtumiaji.

Usanidi

Wacha tuangalie maagizo ya usanidi chaguo-msingi:

Jina la mwongozo Thamani chaguomsingi Vidokezo
kipindi.hifadhi_njia ""
kikao.jina "PHPSESSID"
kipindi.hifadhi_kidhibiti "mafaili"
session.auto_start "0"
session.gc_probability "1"
session.gc_divisor "100" Inapatikana kutoka PHP 4.3.2.
session.gc_maxlifetime "1440"
session.serialize_handler "php"
session.cookie_lifetime "0"
session.cookie_njia "/"
session.cookie_domain ""
session.cookie_salama "" Inapatikana kutoka PHP 4.0.4.
session.use_cookies "1"
session.use_only_cookies "0" Inapatikana kutoka PHP 4.3.0.
session.referer_check ""
session.entropy_file ""
kipindi.entropy_length "0"
session.cache_limiter "nocache"
session.cache_expire "180"
session.use_trans_sid "0" Inapatikana kutoka PHP 4.0.3.
session.bug_compat_42 "1" Inapatikana kutoka PHP 4.3.0.
session.bug_compat_warn "1" Inapatikana kutoka PHP 4.3.0.
kipindi.hash_function "0" Inapatikana kutoka PHP 5.0.0.
session.hash_bits_per_charct "4" Inapatikana kutoka PHP 5.0.0.
url_rewriter.tags "a=href,eneo=href,frame=src,form=,fieldset=" Inapatikana kutoka PHP 4.0.4.

Mfumo wa usimamizi wa kipindi unaauni chaguo kadhaa za usanidi ambazo unaweza kuweka katika faili yako ya php.ini. Tutatoa muhtasari mfupi.

    session.save_handler hubainisha jina la kidhibiti kwa ajili ya kuhifadhi na kuomba data inayohusishwa na kipindi. Kwa faili chaguo-msingi .

    session.save_path inabainisha hoja inayopitishwa kuhifadhi kidhibiti. Ikiwa umechagua kidhibiti chaguo-msingi cha faili, hii itakuwa njia ambayo faili zinaundwa. Chaguo msingi ni /tmp. Ikiwa kina cha njia cha session.save_path ni kikubwa kuliko 2, mkusanyiko wa taka hautafanyika.

    session.name hubainisha jina la kipindi, ambalo hutumika kama jina la kidakuzi. Ni lazima iwe na herufi na nambari pekee. Chaguo-msingi ni PHPSESSID.

    session.auto_start inabainisha kama sehemu ya vipindi itaanza kipindi kiotomatiki kwa ombi la kuanza. Chaguo-msingi ni 0 (imezimwa).

    session.cookie_lifetime hubainisha muda wa kuhifadhi vidakuzi kwa sekunde. Thamani ya 0 inamaanisha "mpaka kivinjari kifungwe." Chaguomsingi ni 0.

    session.serialize_handler inafafanua jina la kidhibiti kwa usanifu/kuondoa data. Hivi sasa miundo ya ndani ya PHP (jina php) na WDDX (jina wddx) inatumika. WDDX inapatikana tu wakati PHP imeundwa kwa usaidizi wa WDDX. Kwa chaguo-msingi php.

    session.gc_probability inabainisha uwezekano wa asilimia kwamba matumizi ya gc (ukusanyaji wa takataka) itaanza kwa kila ombi. Chaguomsingi ni 1.

    session.gc_maxlifetime hubainisha idadi ya sekunde ambazo baada ya hapo data itachukuliwa kuwa "takataka" na kufutwa.

    session.referer_check ina kamba ndogo ambayo unaweza kuangalia kwa kila ombi la HTTP. Ikiwa ombi lilitumwa na mteja na kifungu kidogo hakikupatikana, kitambulisho cha kipindi kilichopachikwa kitatiwa alama kuwa si sahihi. Chaguo-msingi ni mfuatano tupu.

    session.entropy_file inabainisha njia ya rasilimali ya nje (faili) ambayo itatumika kama chanzo cha ziada katika mchakato wa kuunda kitambulisho cha kipindi. Mifano: /dev/random au /dev/urandom, ambayo inapatikana kwenye mifumo mingi ya Unix.

    session.entropy_length inabainisha idadi ya baiti ambazo zitasomwa kutoka kwa faili iliyobainishwa hapo juu. Chaguo-msingi ni 0 (imezimwa).

Unapoendelea kujifunza PHP, labda utatumia kipengele kama vipindi, au hata kusikia kuihusu mara kwa mara. Katika makala hii nitazungumzia juu yao kwa undani zaidi na kutumia mifano wazi ili kuchambua kanuni yao ya uendeshaji. Pia nitakuambia wapi na jinsi zinaweza kutumika kwa kawaida.

Kikao ni nini? Vipindi hukuruhusu kufanya aina ya muunganisho kati ya tovuti yenyewe na mtumiaji kwa kutumia kitambulisho cha kipindi. Vigezo vyote vya kikao na maadili yao huhifadhiwa kwenye seva pekee. Mtumiaji, pamoja na seva, huhifadhi vitambulisho vya kikao pekee, ambavyo vinazalishwa kwa nasibu;

Kitambulisho cha kikao kilichohifadhiwa kwa upande wa mteja (kwenye kompyuta yake) ni faili kuki. Vidakuzi huhifadhiwa kwenye kivinjari cha mtumiaji, lakini faili inayolingana pia huundwa kwenye seva.

Wacha tufanye mazoezi moja kwa moja.

Unda kipindi:

Njia ya msingi hapa ni kutumia session_start kazi:

1 2 // Anza kikao session_start();

// Anzisha kikao_start();

Chaguo hili la kukokotoa hukagua ikiwa kuna kitambulisho cha kipindi; ikiwa hakipo, hukiunda. Na ikiwa inapatikana, basi inapakia vigezo vilivyosajiliwa kutoka kwa kikao kilichopo.

Muundo huu unapaswa kuitwa mara moja tu kwa kila ukurasa na kabla ya pato lolote (sheria hii inatumika pia kwa setcookie()).

Acha nikupe mfano: kipindi kinapoundwa kwenye kivinjari, kidakuzi hapo kinaonekana kama hii:

Kipindi kinapoundwa, kidakuzi kifuatacho kinatumwa kwa kivinjari:

1 2 mwangwi "Jina la kikao:". session_name(). "Kitambulisho cha kikao:". session_id(); // Jina la Kikao: Kitambulisho cha Kikao cha PHPSESSID: mceu371l97id3sa0vcbjqnht06

mwangwi "Jina la kipindi: ".session_name(). " Kitambulisho cha Kipindi: ".session_id(); // Jina la Kikao: Kitambulisho cha Kikao cha PHPSESSID: mceu371l97id3sa0vcbjqnht06

Wacha tuunde tofauti ya kikao:

Tofauti ya kikao inaweza kuundwa kwa kuongeza thamani fulani kwa kipengele cha ulimwengu mkuu cha $_SESSION safu:

haijawekwa($_SESSION["ingia"]);

Njia iliyo hapo juu ni nzuri, lakini unaweza kufuta safu nzima ya $_SESSION, na hivyo kuondoa anuwai zote kwenye kikao:

1 2 // Safisha safu yetu ya $_SESSION$_SESSION = safu ();

// Futa safu yetu $_SESSION $_SESSION = safu();

2. Sasa tunahitaji kubatilisha kidakuzi (ambapo jina la kipindi linarejelewa wakati wa kufikia kitambulisho cha kipindi katika kidakuzi na URL):

1 2 3 ikiwa (imewekwa ($_COOKIE [ session_name () ] ) ) ( // session_name() - toa jina la kikao cha sasa setcookie (session_name () , "", muda () - 86400 , "/" ); )

ikiwa (isset($_COOKIE)) ( // session_name() - vuta nje jina la kikao cha sasa setcookie(session_name(), "", time()-86400, "/"); )

3. Naam, ijayo tutaharibu kikao (kuifunga):

session_start(); ob_start();

Hapa kuna mfano wa kina zaidi wa nambari kwa kutumia nambari na kazi zilizojadiliwa hapo awali:

1 2 3 4 5 6 7 8 9 ikiwa (imewekwa ($_SESSION [ "login" ] ) ) ( echo "Hujambo, " . $_SESSION [ "name" ] . " " ; haijawekwa ($_SESSION [ "login" ] ) ; ikiwa (imewekwa ($_COOKIE [ session_name () ] ) ) (setcookie (jina_la_kipindi () , "", wakati () - 86400 , "/" ) ; // maudhui ya kikao chetu ni kamba tupu) ob_end_flush (); // Tuma pato kwa kivinjari session_destroy();

ikiwa (isset($_SESSION["ingia"])) ( echo "Hujambo, " . $_SESSION["name"] . " "; haijawekwa($_SESSION["login"]); ikiwa (isset($_COOKIE)) ( setcookie(session_name(), "", time()-86400, "/");// maudhui ya kipindi chetu ni kamba tupu ) ob_end_flush( // Tuma pato kwa kikao cha kivinjari_destroy();

Walakini, inafaa kuzingatia kwamba kutumia ob_end_flush() kazi sio lazima kila wakati. Na yote kwa sababu mkalimani wa PHP husafisha kiotomatiki bafa yako wakati wa kutekeleza hati fulani.

Wacha tuunda upya kitambulisho cha kikao:

Kila wakati unapoingia kwenye mfumo, kwa sababu za usalama, ni muhimu kuunda upya kitambulisho cha kikao. Taarifa zote katika vigezo vya kikao chako huhifadhiwa kwenye seva yako ya wavuti katika mfumo wa maandishi wazi katika faili maalum, taarifa zote kuhusu vigeu vinavyotumika katika kipindi huhifadhiwa na kitambulisho cha kipindi pekee ndicho kinachobadilika. Ili kutengeneza upya kitambulisho cha kipindi, tumia kitendakazi cha session_regenerate_id(), kisha, ukimaliza, onyesha upya ukurasa uliopo au umtume mtumiaji kwa ukurasa mwingine kwa kutumia uelekezaji upya.

Jinsi vipindi hufanya kazi:

Katika picha ya skrini hapa chini unaweza kuona muhtasari mfupi wa utaratibu wa kikao yenyewe.

Wacha tupunguze maisha ya kikao:

Kiwango cha kawaida cha maisha ya kipindi ni 0, yaani, ikiwa mtumiaji atafunga dirisha la kivinjari, kipindi pia kitafungwa. Lakini wakati mwingine kuna haja ya kuharibu kikao cha mteja kwa nguvu baada ya muda fulani kupita, kwa mfano kutokana na kutokuwa na kazi kwa upande wake kwenye tovuti. Wacha tuangalie njia ya utekelezaji kama huo kwa kutumia mfano wa idhini ya mtumiaji: tutaunda aina fulani ya kutofautisha na kuhifadhi ndani yake wakati unaotumika wakati wa idhini ya mtumiaji, kwa mfano, ikiwa mtumiaji anajaribu kuvinjari ukurasa, basi tunalinganisha muda na muda ambao alikuwa hafanyi kazi, na ikiwa imezidi kiwango hiki, atatolewa na kutumwa kwa ukurasa wa idhini.

1 2 3 4 5 6 7 8 $_SESSION["start"] = muda(); // Kuanza kwa wakati ambapo mtumiaji aliingia$timezon = wakati(); // Wakati huu (ile iliyopo sasa)$time_limit = 2000 ; // Huu ndio muda wa juu zaidi ambao mtumiaji hana amilifu ikiwa ($timezon > $_SESSION [ "start" ] + $time_limit ) ( mwangwi "Wakati umekwisha"; ) kwingine ( $_SESSION [ "start" ] = muda () ;) // ikiwa kila kitu ni nzuri, basi sasisha

$_SESSION["start"] = muda(); // Kuanza kwa wakati ambapo mtumiaji aliingia $timezon= time(); // Wakati huu (ile iliyopo sasa) $time_limit = 2000; // Huu ndio muda wa juu zaidi ambao mtumiaji ataacha kutumika ikiwa ($timezon> $_SESSION["start"] + $time_limit) ( echo "Muda umekwisha"; ) vinginevyo ($_SESSION["start"] = time(); ) // ikiwa kila kitu kiko sawa, wacha tusasishe

Wakati mwingine watu wana swali "Jinsi ya kutekeleza kipindi kisicho na mwisho cha maisha?", hapa nitakupa jibu. Hii haipaswi kufanywa, kimsingi sio sawa na wazo. Kikao kiliundwa kwa madhumuni ya mtumiaji kutembelea tovuti - ilifungua, aliondoka - imefungwa (imeharibiwa). Alipoingia tena, kikao kipya kilifunguliwa. Hata hivyo, unaweza kutumia data kutoka kwa vidakuzi kwa kipindi, ambacho kinaweza kuhifadhiwa kwa muda mrefu, kwa mfano, unapotumia kisanduku cha kuteua cha "Unikumbuke" (Je, unaikumbuka kwenye tovuti?)...

Kutumia vipindi vilivyo na vidakuzi vimezimwa:

Niambie hii haifanyiki? Kwa bahati mbaya, hii pia hufanyika wakati mwingine. Kwa mfano, ikiwa tutaweka mpangilio wa session.use_trans_sid kuwa 1, basi bila kidakuzi, PHP itapitisha vigezo vya PHPSESSID kwa kutumia mbinu ya GET katika mstari wa ombi lako.

Hiyo ndiyo yote, makala imekamilika. Ikiwa bado una maswali kuhusu matumizi ya vikao, au labda una nyongeza au maoni, unaweza kuacha kila kitu katika maoni kwa makala hii.

Kushughulikia kipindi ni mbinu muhimu katika PHP ambayo inaruhusu data ya mtumiaji kuhifadhiwa kwenye kurasa zote za tovuti au programu. Katika makala hii utajifunza misingi ya kushughulikia kikao katika PHP.

Tutaanza kwa kueleza jinsi vipindi hufanya kazi na jinsi vinavyohusiana na vidakuzi. Kisha tutaangalia vijisehemu vichache vya msimbo vinavyoonyesha jinsi ya kufanya kazi na vipindi. Utajifunza jinsi ya kuunda na kuharibu vipindi na jinsi ya kubadilisha vigezo vya kikao.

Ni nini kikao katika PHP?

Kipindi ni utaratibu wa kuhifadhi taarifa kwenye kurasa za wavuti ili kutambua watumiaji wanapopitia tovuti au programu. Je, unashangaa kwa nini vikao vinahitajika kwa tovuti? Ili kuelewa kwa nini vipindi ni muhimu, tunahitaji kurudi nyuma kidogo na kuangalia jinsi itifaki ya HTTP inavyofanya kazi.

Itifaki ya HTTP ni itifaki isiyo na uraia, ambayo ina maana kwamba seva haiwezi kulingana na mtumiaji mahususi katika maombi mengi. Kwa mfano, wakati wa kufikia ukurasa wa wavuti, seva inawajibika kutoa yaliyomo kwenye ukurasa ulioombwa. Kwa hivyo unapofikia kurasa zingine kwenye wavuti hiyo hiyo, seva ya wavuti hutafsiri kila ombi kando, kana kwamba hazihusiani. Seva haijui kuwa kila ombi linatoka kwa mtumiaji yule yule.

Mchoro ufuatao unaonyesha kwa ufupi itifaki ya HTTP.

Katika mfano huu, ikiwa unataka kuonyesha maelezo ya mtumiaji, utahitaji kuthibitisha mtumiaji kwa kila ombi. Hebu fikiria ikiwa utalazimika kuingiza jina lako la mtumiaji na nenosiri kwenye kila ukurasa wa data yako! Ndio, hii itakuwa ngumu na kwa ujumla sio ya vitendo, na hapa ndipo vikao vinakuja kuwaokoa.

Kipindi hukuruhusu kubadilishana habari kati ya kurasa tofauti za tovuti au programu moja, na husaidia kudumisha hali. Hii inaruhusu seva kujua kwamba maombi yote yanatoka kwa mtumiaji mmoja, na kuruhusu tovuti kuonyesha maelezo na mapendeleo ya mtumiaji.

Kushughulikia kuingia na vikao na vidakuzi

Wacha tuangalie haraka mfano wa kawaida wa kuingia kwenye wavuti ili kuelewa kinachoendelea nyuma ya pazia.

  1. Mtumiaji hufungua ukurasa wa kuingia kwenye tovuti.
  2. Baada ya kuwasilisha fomu ya kuingia, seva katika mwisho mwingine inathibitisha ombi kwa kuangalia sifa zilizoingizwa.
  3. Ikiwa kitambulisho kilichowekwa na mtumiaji ni sahihi, seva itaunda kipindi kipya. Seva hutengeneza nambari ya kipekee ya nasibu inayoitwa Kitambulisho cha kipindi. Pia, faili mpya imeundwa kwenye seva, ambayo hutumiwa kuhifadhi habari zinazohusiana na kikao.
  4. Kisha, kitambulisho cha kikao kinarudishwa kwa mtumiaji, pamoja na chochote alichoomba. Nyuma ya pazia, kitambulisho hiki cha kikao kinatumwa kwa kichwa cha majibu ya kidakuzi cha PHPSESSID (hicho ndicho kinachoitwa kwa chaguo-msingi).
  5. Wakati kivinjari kinapokea jibu kutoka kwa seva, hupokea kichwa cha kidakuzi cha PHPSESSID. Ikiwa kivinjari chako kinaruhusu vidakuzi, kitahifadhi PHPSESSID hii, ambayo huhifadhi kitambulisho cha kipindi kilichotumwa na seva.
  6. Kwa maombi yanayofuata, kidakuzi cha PHPSESSID kinarudishwa kwa seva. Seva inapopokea kidakuzi cha PHPSESSID, hujaribu kuanzisha kipindi kwa kutumia kitambulisho hicho cha kipindi. Inafanya hivyo kwa kupakia faili ya kikao ambayo iliundwa mapema wakati wa uanzishaji wa kikao. Kisha huanzisha utofauti wa safu ya juu zaidi $_SESSION na data iliyohifadhiwa kwenye faili ya kipindi.

Kwa njia hii, data ya mtumiaji huhifadhiwa hata katika maombi mengi na mtumiaji hatapotea katika kipindi chote.

Mchoro ufuatao unaonyesha jinsi itifaki ya HTTP inavyofanya kazi na vipindi.

Sasa kwa kuwa umeona utangulizi mfupi wa jinsi vipindi hufanya kazi, tutaunda baadhi ya mifano ya vitendo ili kuonyesha jinsi ya kuunda na kuendesha vigeu vya vipindi.

Jinsi ya kuanza kikao

Katika sehemu hii, tutajadili jinsi ya kuanza kikao katika PHP.

Wakati wowote unapotaka kufanya kazi na anuwai za kikao, unahitaji kuhakikisha kuwa kikao tayari kinaendelea. Kuna njia kadhaa za kuanza kikao katika PHP.

Kwa kutumia kitendakazi cha session_start

Njia ambayo kipindi kinaanza na session_start ni kitu ambacho utaona mara kwa mara.

Ni muhimu kwamba kazi ya session_start inaitwa mwanzoni mwa hati, kabla ya kutuma chochote kwa kivinjari. Vinginevyo, utakumbana na makosa ya Vichwa vilivyotumwa tayari.

Kipindi kiotomatiki kinaanza

Ikiwa unahitaji kutumia vipindi katika programu yako, inawezekana kuanza kipindi kiotomatiki bila kutumia kitendakazi cha session_start.

Katika faili php.ini Kuna parameta session.auto_start inayokuruhusu kuanza kipindi kiotomatiki kwa kila ombi. Thamani chaguo-msingi ni 0 (imezimwa), na unaweza kuiweka 1 (imewashwa) ili kuwezesha kipengele cha kuanza kiotomatiki.

Session.auto_start = 1

Kwa upande mwingine, ikiwa hauna ufikiaji wa faili php.ini na unatumia seva ya wavuti ya Apache, utofauti huu unaweza kuwekwa kwa kutumia faili .htaccess.

Php_value session.auto_start 1

Ikiwa unaongeza mstari hapo juu kwa yako .htaccess faili, basi hii inapaswa kuzindua vikao kiotomatiki katika programu yako ya PHP.

Jinsi ya kupata kitambulisho cha kikao

Kama tulivyojadili hapo awali, seva huunda nambari ya kipekee kwa kila kipindi kipya. Ikiwa ungependa kupata kitambulisho cha kipindi, unaweza kutumia kitendakazi cha session_id kama inavyoonyeshwa kwenye kijisehemu kifuatacho.

Hii inapaswa kukupa kitambulisho cha kikao cha sasa. Kitendaji cha kitambulisho cha session_id kinavutia kwa sababu kinaweza kuchukua hoja moja - kitambulisho cha kipindi. Ikiwa ungependa kubadilisha kitambulisho cha kipindi kinachozalishwa na mfumo na chako, unaweza kufanya hivyo kwa kupitisha hoja ya kwanza kwenye kitendakazi cha session_id.

Ni muhimu kutambua kwamba ikiwa unataka kuanzisha kipindi kwa kutumia kitambulisho cha kipindi chako, kipengele cha kitendakazi cha session_id lazima kije kabla ya kikao_kuanza simu.

Kuunda Vigezo vya Kikao

Katika sehemu hii, tutajifunza jinsi ya kuanzisha vigezo vya kikao katika PHP.

Kama tulivyojadili tayari, kipindi kinapoanzishwa, safu ya juu zaidi ya $_SESSION inaanzishwa kwa maelezo yanayolingana ya kipindi. Kwa chaguo-msingi, huanzishwa kama safu tupu, na unaweza kuhifadhi maelezo zaidi kwa kutumia jozi ya ufunguo-thamani.

Wacha tuangalie mfano wa nambari ifuatayo, ambayo inaonyesha jinsi ya kuanzisha anuwai za kikao.

Kama unavyoona, tulianza kipindi mwanzoni mwa hati kwa kutumia session_start. Baada ya hayo, tulianzisha vigezo kadhaa vya kikao. Hatimaye, tulitumia vigeu hivi kupitia $_SESSION utofauti wa ulimwengu mzima.

Wakati wa kuhifadhi data ya kipindi kwa kutumia $_SESSION , huishia kuhifadhiwa katika faili inayolingana ya kipindi kwenye seva ambayo iliundwa wakati kipindi kilipoanzishwa. Kwa njia hii, data ya kikao inashirikiwa kati ya maombi mengi.

Kama tulivyoona tayari, habari ya kikao hupitishwa pamoja na maombi, kwa hivyo anuwai za kikao zilizoanzishwa kwenye ukurasa mmoja zinaweza kupatikana kwenye kurasa zingine, na pia hadi mwisho wa kipindi. Kama sheria, vipindi huisha wakati kivinjari kimefungwa.

Jinsi ya kubadilisha na kufuta vijiti vya kikao

Unaweza kurekebisha au kufuta vigeu vya kikao ambavyo viliundwa hapo awali katika programu yako, kama vile vigeu vya kawaida vya PHP.

Hebu tuone jinsi ya kubadilisha vigezo vya kikao.

Katika msimbo ulio hapo juu, tunaangalia ili kuona kama kigezo cha $_SESSION["count"] kimewekwa. Ikiwa haijawekwa, tunaiweka kuwa 1, vinginevyo tunaiongeza kwa 1. Kwa hivyo ukionyesha upya ukurasa huu mara kadhaa, unapaswa kuona kaunta ikiongezeka kwa moja kila wakati!

Kwa upande mwingine, ikiwa unataka kuondoa utofauti wa kipindi, unaweza kutumia chaguo la kukokotoa ambalo halijawekwa kama inavyoonyeshwa kwenye kijisehemu kifuatacho.

Kwa hivyo hutaweza tena kufikia $_SESSION["logged_in_user_id"] tofauti kwa kuwa imeondolewa na chaguo la kukokotoa ambalo halijawekwa. Hivi ndivyo unavyoweza kubadilisha maelezo ya kikao.

Jinsi ya kuharibu kikao

Katika sehemu hii, tutaona jinsi tunaweza kuharibu kikao. Katika sehemu iliyopita, tuliangalia kazi isiyowekwa, ambayo hutumiwa kuondoa vigezo fulani vya kikao. Kwa upande mwingine, ikiwa unataka kufuta data yote inayohusishwa na kipindi mara moja, unaweza kutumia kitendakazi cha session_destroy.

Hebu jaribu kuelewa jinsi hii inavyofanya kazi katika mfano ufuatao.

Kitendaji cha session_destroy kinafuta kila kitu kilichohifadhiwa katika kipindi cha sasa. Kwa hivyo, pamoja na maombi yanayofuata utaona tofauti tupu ya $_SESSION kwa sababu data ya kipindi iliyohifadhiwa kwenye diski ilifutwa na kitendakazi cha session_destroy.

Kwa kawaida, kitendakazi cha session_destroy kinapaswa kutumiwa mtumiaji anapotoka.

Hitimisho

Katika nakala hii, tulijifunza misingi ya kushughulikia kikao katika PHP. Hii ni dhana muhimu ambayo itawawezesha kuhifadhi habari kwa kurasa za wavuti.

Katika nusu ya kwanza ya makala, tulijadili dhana za kimsingi za vipindi, na kisha tukaunda baadhi ya mifano katika PHP ili kuonyesha jinsi unavyoweza kuunda na kuharibu vipindi, na kuendesha vigeu vya vipindi.

Vikao ni utaratibu unaokuwezesha kuhifadhi data fulani kwenye seva, ya kipekee kwa kila mtumiaji. Wasomaji makini hasa watatambua kufanana na kuki. Na, kwa ujumla, ni kitu kimoja. Walakini, jambo kuu: data haijahifadhiwa kwenye kivinjari cha mtumiaji, lakini katika faili maalum kwenye seva, ambaye jina lake ni la kipekee kwa kila mtumiaji. Ya kipekee Kitambulisho cha kipindi cha PHP tayari kuhifadhiwa ndani kuki.

Twende nawe Wacha tufanye kazi na vikao katika PHP. Na tuanze na session_start() kazi. Kitendaji hiki hufanya yafuatayo: ikiwa mtumiaji ataingia kwa mara ya kwanza, huunda kitambulisho cha kipekee na kukiandikia. kuki, na pia huunda faili mpya, tena ya kipekee kwa mtumiaji. Ikiwa mtumiaji tayari ameingia, basi seva inasoma thamani ya kitambulisho cha kipekee kutoka kuki na, kwa mujibu wake, hupata faili ya kikao kinachohitajika. Kutoka kwa faili hii PHP inasoma data zote na kuiweka katika safu $_SESSION. Hebu tuandike msimbo rahisi ambao tunaandika kutofautiana kwa kikao, au tusome ikiwa tayari imeandikwa.

session_start();
ikiwa (isset($_SESSION["jina"])) $name = $_SESSION["jina"];
else $_SESSION["name"] = "15St";
echo $jina;
?>

Kwanza tunaita session_start() kazi niliyoeleza hapo juu. Kisha tunaangalia ikiwa kutofautisha "kupo" jina" kwenye kikao. Ikiwa iko, basi tunasoma data kutoka kwayo na kuiandika kwa kutofautisha jina. Ikiwa haipo (hiyo ni, mtumiaji alikuja kwa mara ya kwanza), basi weka kutofautisha " jina"katika thamani ya kikao" 15 St.". Mstari unaofuata unaonyesha thamani ya kutofautisha $jina. Ni wazi, mara ya kwanza ukiiendesha, utaona laini tupu, lakini mara ya pili ukiiendesha, utaona mstari " 15 St.", soma kutoka kwenye kikao.

Ninakushauri sasa uingie kwenye bar ya anwani: " javascript:document.cookie" (ingia kwenye kichupo sawa na ulivyoendesha hati). Kama matokeo, utaona kitu kama hiki: " PHPSESSID=". Maana tu PHPSESSID na hivyo ni kitambulisho cha kipekee.

Na kufanya kila kitu wazi kabisa, mimi kukushauri hata kupata faili ya kikao. Ikiwa unatumia Denwer, basi iko kwenye folda " tmp". Angalia faili zinazoanza na " ses_"- hawa ndio sana faili za kikao. Unaweza kuzifungua kwenye daftari rahisi.

Mali nyingine muhimu sana ni Muda wa vikao katika PHP. Kisha ikiwa kuki huhifadhiwa hadi zifutwe na kivinjari. Na kivinjari hakizifuta kwa chaguo-msingi. Kisha vipindi huhifadhiwa kwa muda uliowekwa ndani Mipangilio ya PHP. Kwa msingi, hii ni 15 dakika. Hiyo ni, ikiwa unatumia uthibitishaji wa msingi wa kikao, kisha baada ya dakika 15 kutochukua hatua mtumiaji, atalazimika kuingia tena. Kwa kweli, hii ni nzuri, kwa sababu ikiwa mtumiaji atasahau " Nenda nje", basi hakuna chochote kibaya kitatokea. Mshambulizi hataweza kutumia akaunti ya mtumiaji. Zaidi ya hayo, ikiwa matumizi ya vidakuzi zinaweza kuibiwa, kubadilishwa katika kivinjari chako, na kwa sababu hiyo mshambuliaji ameidhinishwa kwa kutumia data ya mtu mwingine, bila hata kujua nenosiri. Lakini haitawezekana kuiba kikao, kwani vigezo vyote vimehifadhiwa kwenye seva, na hakuna njia ya kujua juu yao.

Kwa hiyo, jaribu katika mazoezi yako hasa tumia vipindi, sio safi kuki.

Na hatimaye, ningependa kukuonya kuhusu kosa la kawaida sana. Usiwahi kutoa data kwa vivinjari hapo awali kwa kutumia session_start() kazi, vinginevyo itatupa kosa. Hiyo ni, huwezi kuandika kama hii:

echo "Halo";
session_start();
?>

Hitilafu itatokea wakati wa kuendesha hati hii. Sheria hiyo hiyo inatumika na kuki (setcookie() kazi) Kwa hiyo, nadhani kila kitu kiko wazi hapa.

Kuhusu vipindi katika PHP, basi, bila shaka, zinaweza kutumika kuhifadhi takwimu, uthibitishaji, mipangilio ya mtumiaji binafsi na mambo mengine sawa.

Salamu, jumuiya mpendwa.

Kwanza kabisa, nataka kukushukuru kwa rasilimali muhimu sana. Zaidi ya mara moja nimepata mawazo mengi ya kuvutia na ushauri wa vitendo hapa.

Madhumuni ya kifungu hiki ni kuangazia mitego ya kutumia vipindi katika PHP. Kwa kweli, kuna hati za PHP na mifano mingi, na nakala hii haikusudiwa kuwa mwongozo kamili. Imeundwa ili kufichua baadhi ya nuances ya kufanya kazi na vikao na kulinda watengenezaji kutokana na upotevu wa muda usio wa lazima.

Mfano wa kawaida wa kutumia vikao ni, bila shaka, idhini ya mtumiaji. Wacha tuanze na utekelezaji wa kimsingi zaidi ili kuikuza polepole kazi mpya zinapoibuka.

(Ili kuokoa nafasi na wakati, tutaweka kikomo kwa mifano yetu kwa utendakazi wa kikao chenyewe, badala ya kujenga hapa maombi kamili ya mtihani na uongozi mzuri wa darasa, utunzaji wa makosa ya kina na mambo mengine mazuri).

Kazi startSession() ( // Ikiwa kipindi tayari kimeanzishwa, acha kutekeleza na urudishe TRUE // (kigezo cha session.auto_start katika faili ya mipangilio ya php.ini lazima izimishwe - thamani chaguomsingi) ikiwa (session_id()) itarudi. true; else return session_start();// Kumbuka: Kabla ya toleo la 5.3.0, kitendakazi cha session_start() kilirejesha TRUE hata kama kulikuwa na hitilafu // Ikiwa unatumia toleo la mapema zaidi ya 5.3.0, fanya ukaguzi wa ziada kwa session_id() // baada ya kuita session_start() kitendakazi haribuSession() (ikiwa (session_id()) ( // Ikiwa kuna kipindi kinachoendelea, futa vidakuzi vya kikao, setcookie(session_name(), session_id(), time(). )-60*60*24 na uharibu kikao_kisichowekwa();

Kumbuka: Inachukuliwa kuwa msomaji ana maarifa ya kimsingi kuhusu vipindi vya PHP, kwa hivyo hatutashughulikia kanuni ya utendakazi wa session_start() na session_destroy() kazi hapa. Kazi za mpangilio wa fomu ya kuingia na uthibitishaji wa mtumiaji hazihusiani na mada ya makala, kwa hiyo tutawaacha pia. Acha nikukumbushe tu kwamba ili kutambua mtumiaji katika kila ombi linalofuata, wakati wa kuingia kwa mafanikio, tunahitaji kuhifadhi kitambulisho cha mtumiaji katika muundo wa kikao (kinachoitwa userid, kwa mfano), ambacho kitapatikana katika maombi yote yanayofuata ndani. maisha ya kikao. Ni muhimu pia kutekeleza usindikaji wa matokeo ya kazi yetu ya startSession(). Ikiwa kazi inarudi FALSE, onyesha fomu ya kuingia kwenye kivinjari. Ikiwa chaguo la kukokotoa limerejeshwa TRUE, na tofauti ya kikao iliyo na kitambulisho cha mtumiaji aliyeidhinishwa (kwa upande wetu - userid), ipo - onyesha ukurasa wa mtumiaji aliyeidhinishwa (kwa habari zaidi kuhusu kushughulikia makosa, angalia nyongeza ya 2013-06- 07 katika sehemu ya vigezo vya kikao).

Hadi sasa kila kitu kiko wazi. Maswali huanza wakati unahitaji kutekeleza udhibiti wa kutotumika kwa mtumiaji (muda wa kipindi umekwisha), wezesha watumiaji wengi kufanya kazi kwa wakati mmoja katika kivinjari kimoja, na pia kulinda vipindi dhidi ya matumizi yasiyoidhinishwa. Hii itajadiliwa hapa chini.

Kufuatilia kutotumika kwa mtumiaji kwa kutumia zana za PHP zilizojengewa ndani

Swali la kwanza ambalo mara nyingi hutokea kati ya watengenezaji wa kila aina ya consoles kwa watumiaji ni kukomesha kiotomatiki kwa kipindi katika tukio la kutofanya kazi kwa sehemu ya mtumiaji. Hakuna kitu rahisi kuliko kufanya hivyo kwa kutumia uwezo uliojengwa wa PHP. (Chaguo hili sio la kuaminika sana au rahisi, lakini tutazingatia kwa ukamilifu).

Kazi startSession() ( // Muda wa kutotumika kwa mtumiaji (kwa sekunde) $sessionLifetime = 300; ikiwa (session_id()) itarudi kuwa kweli; // Weka maisha ya kidakuzi ini_set("session.cookie_lifetime", $sessionLifetime); // Ikiwa mtumiaji muda wa kutotumika umewekwa, weka kipindi cha maisha kwenye seva // Kumbuka: Kwa seva ya uzalishaji, inashauriwa kuweka vigezo hivi mapema katika faili ya php.ini ikiwa ($sessionLifetime) ini_set("session.gc_maxlifetime", $sessionLifetime ikiwa (session_start(); )) ( setcookie(session_name(), session_id(), time()+$sessionLitimeme); rudisha true; ) vinginevyo rudisha sivyo)

Ufafanuzi machache. Kama unavyojua, PHP huamua ni kipindi kipi kinahitaji kuzinduliwa kwa jina la kidakuzi lililotumwa na kivinjari kwenye kichwa cha ombi. Kivinjari, kwa upande wake, hupokea kuki hii kutoka kwa seva, ambapo kitendaji cha session_start() kinaiweka. Ikiwa kidakuzi cha kivinjari kimeisha muda wake, hakitatumwa katika ombi, kumaanisha kwamba PHP haitaweza kubainisha kipindi kipi cha kuanza na itachukulia hili kama kuunda kipindi kipya. Kigezo cha mipangilio ya PHP session.gc_maxlifetime, ambacho kimewekwa sawa na muda wa kutotumika kwa mtumiaji, huweka muda wa maisha wa kipindi cha PHP na kudhibitiwa na seva. Kudhibiti maisha ya kipindi hufanya kazi kama ifuatavyo (hapa tunazingatia mfano wa kuhifadhi vipindi katika faili za muda kama chaguo la kawaida na chaguo-msingi katika PHP).

Kipindi kipya kinapoundwa, faili inayoitwa sess_ huundwa katika saraka iliyowekwa kama saraka ya hifadhi ya kipindi katika kigezo cha mipangilio ya PHP session.save_path , Wapi - kitambulisho cha kikao. Ifuatayo, katika kila ombi, wakati wa kuzindua kikao kilichopo tayari, PHP inasasisha wakati wa urekebishaji wa faili hii. Kwa hivyo, katika kila ombi linalofuata, PHP, kwa tofauti kati ya wakati wa sasa na wakati wa marekebisho ya mwisho ya faili ya kikao, inaweza kuamua ikiwa kipindi kinatumika au muda wa maisha tayari umekwisha. (Mbinu ya kufuta faili za kikao cha zamani inajadiliwa kwa undani zaidi katika sehemu inayofuata.)

Kumbuka: Ikumbukwe hapa kwamba parameta ya session.gc_maxlifetime inatumika kwa vipindi vyote ndani ya seva moja (kwa usahihi zaidi, ndani ya mchakato mmoja mkuu wa PHP). Kwa mazoezi, hii ina maana kwamba ikiwa tovuti kadhaa zinaendesha kwenye seva, na kila mmoja wao ana muda wake wa kutofanya kazi kwa mtumiaji, basi kuweka parameter hii kwenye moja ya tovuti itasababisha kuweka kwa tovuti nyingine. Vile vile inatumika kwa upangishaji pamoja. Ili kuepuka hali hii, saraka za vipindi tofauti hutumiwa kwa kila tovuti ndani ya seva moja. Kuweka njia kwenye saraka ya vikao hufanyika kwa kutumia parameter ya session.save_path katika faili ya mipangilio ya php.ini, au kwa kupiga kazi ya ini_set (). Baada ya hayo, vipindi vya kila tovuti vitahifadhiwa katika saraka tofauti, na kigezo cha session.gc_maxlifetime kilichowekwa kwenye mojawapo ya tovuti kitakuwa halali kwa kipindi chake pekee. Hatutazingatia kesi hii kwa undani, hasa kwa kuwa tuna chaguo rahisi zaidi la kufuatilia kutotumika kwa mtumiaji.

Kudhibiti kutotumika kwa mtumiaji kwa kutumia vigeu vya vipindi

Inaweza kuonekana kuwa chaguo la awali, kwa unyenyekevu wake wote (tu ya mistari michache ya ziada ya kanuni), inatoa kila kitu tunachohitaji. Lakini vipi ikiwa sio kila ombi linaweza kuzingatiwa kama matokeo ya shughuli za watumiaji? Kwa mfano, ukurasa una kipima muda ambacho mara kwa mara hufanya ombi la AJAX ili kupokea masasisho kutoka kwa seva. Ombi kama hilo haliwezi kuchukuliwa kama shughuli ya mtumiaji, ambayo inamaanisha kuwa kuongeza muda wa kipindi kiotomatiki si sahihi katika kesi hii. Lakini tunajua kuwa PHP husasisha muda wa urekebishaji wa faili ya kikao kiotomatiki kila wakati session_start() chaguo la kukokotoa linapoitwa, ambayo ina maana kwamba ombi lolote litasababisha upanuzi wa muda wa kipindi, na muda wa kutofanya kazi kwa mtumiaji hautawahi kutokea. Kwa kuongeza, dokezo la mwisho kutoka sehemu iliyotangulia kuhusu utata wa kigezo cha session.gc_maxlifetime linaweza kuonekana kuwa la kutatanisha na kuwa vigumu kutekeleza kwa baadhi.

Ili kutatua tatizo hili, tutaachana na matumizi ya mifumo ya PHP iliyojengewa ndani na kuanzisha vijiumbe kadhaa vya vipindi vipya ambavyo vitaturuhusu kudhibiti wakati wa kutotumika kwa mtumiaji sisi wenyewe.

Kazi startSession($isUserActivity=true) ($sessionLifetime = 300; ikiwa (session_id()) itarudi kweli; // Weka maisha ya kidakuzi kabla ya kufunga kivinjari (tutadhibiti kila kitu kwenye upande wa seva) ini_set("session. cookie_lifetime", 0) ; ikiwa (! session_start()) itarudi sivyo; $t = time(); ikiwa ($sessionLifetime) ( // Ikiwa muda wa kutotumika wa mtumiaji umewekwa, // angalia muda uliopita tangu shughuli ya mwisho ya mtumiaji // (wakati wa ombi la mwisho) wakati utofauti wa kipindi cha shughuli ya mwisho ulisasishwa) ikiwa (isset($_SESSION["lastactivity"]) && $t-$_SESSION["lastactivity"] >= $sessionLitime) ( // Ikiwa muda ulipita tangu shughuli ya mwisho ya mtumiaji, // ni kubwa kuliko muda wa kutotumika, ambayo ina maana kwamba kipindi kimekwisha na kipindi kinahitaji kukatizwa haribuSession( vinginevyo ( // Ikiwa muda wa kuisha haujafanyika, // na kama ombi lilikuja kama matokeo ya shughuli za mtumiaji, // sasisha utofauti wa shughuli ya mwisho na thamani ya wakati wa sasa, // na hivyo kuongeza muda wa kipindi kwa kipindi kingineSekunde za maisha ikiwa ($isUserActivity) $_SESSION["lastactivity"] = $t; )) kurudi kweli; )

Hebu tufanye muhtasari. Katika kila ombi, tunaangalia kama muda wa kuisha umefikiwa tangu shughuli ya mwisho ya mtumiaji hadi wakati wa sasa, na ikiwa imefikiwa, tunaharibu kipindi na kukatiza utekelezaji wa chaguo la kukokotoa, na kurudisha FALSE. Ikiwa muda wa kuisha haujafikiwa, na kigezo cha $isUserActivity chenye thamani ya TRUE kinapitishwa kwenye chaguo la kukokotoa, tunasasisha muda wa shughuli ya mwisho ya mtumiaji. Tunachopaswa kufanya ni kubainisha katika hati ya kupiga simu ikiwa ombi ni matokeo ya shughuli za mtumiaji, na ikiwa sivyo, piga simu kitendakazi cha startSession na kigezo cha $isUserActivity kimewekwa kuwa FALSE.

Sasisho kutoka 2013-06-07
Inachakata matokeo ya kitendakazi cha sessionStart().

Maoni yalionyesha kuwa kurudisha FALSE hakutoi uelewa kamili wa sababu ya kosa, na hii ni haki kabisa. Sikuchapisha utunzaji wa makosa hapa (urefu wa kifungu tayari ni mkubwa), kwani hii haihusiani moja kwa moja na mada ya kifungu. Lakini kutokana na maoni, nitafafanua.

Kama unavyoona, kipengele cha Kuanzisha kipindi kinaweza kurudisha FALSE katika visa viwili. Labda kipindi hakikuweza kuanzishwa kwa sababu ya baadhi ya hitilafu za ndani za seva (kwa mfano, mipangilio isiyo sahihi ya kipindi katika php.ini), au muda wa kipindi umekwisha. Katika kesi ya kwanza, lazima tuelekeze mtumiaji kwenye ukurasa na hitilafu inayosema kuwa kuna matatizo kwenye seva na fomu ya kuwasiliana na usaidizi. Katika kesi ya pili, lazima tuhamishe mtumiaji kwa fomu ya kuingia na kuonyesha ujumbe unaofanana ndani yake unaosema kuwa kipindi kimekwisha. Ili kufanya hivyo, tunahitaji kuingiza msimbo wa makosa na kurudi msimbo unaofanana badala ya FALSE, na kwa njia ya kupiga simu, angalia na ufanyie kazi ipasavyo.

Sasa, hata kama kipindi kwenye seva bado kipo, kitaharibiwa mara ya kwanza kinapofikiwa ikiwa muda wa kutotumika wa mtumiaji umekwisha. Na hii itafanyika bila kujali ni muda gani wa kipindi umewekwa katika mipangilio ya kimataifa ya PHP.

Kumbuka: Nini kitatokea ikiwa kivinjari kilifungwa na kidakuzi cha jina la kipindi kikaharibiwa kiotomatiki? Ombi kwa seva wakati kivinjari kitafunguliwa tena halitakuwa na vidakuzi vya kipindi, na seva haitaweza kufungua kipindi na kuangalia muda wa kutotumika wa mtumiaji kuisha. Kwetu sisi, hii ni sawa na kuunda kipindi kipya na haiathiri utendakazi au usalama kwa njia yoyote ile. Lakini swali la haki linatokea - ni nani basi ataharibu kikao cha zamani, ikiwa hadi sasa tumekiharibu baada ya muda kuisha? Au sasa itaning'inia kwenye saraka ya vikao milele? Ili kusafisha vikao vya zamani katika PHP, kuna utaratibu unaoitwa ukusanyaji wa takataka. Hufanya kazi wakati wa ombi linalofuata kwa seva na hufuta vipindi vyote vya zamani kulingana na tarehe ya mwisho ya urekebishaji wa faili za kipindi. Lakini utaratibu wa kukusanya takataka hauanza na kila ombi kwa seva. Masafa (au tuseme, uwezekano) wa kuzindua hubainishwa na vigezo viwili vya mipangilio session.gc_probability na session.gc_divisor. Matokeo ya kugawanya parameter ya kwanza kwa pili ni uwezekano wa kuzindua utaratibu wa kukusanya takataka. Kwa hivyo, ili utaratibu wa kusafisha kikao uzinduliwe kwa kila ombi kwa seva, vigezo hivi lazima viweke kwa maadili sawa, kwa mfano "1". Njia hii inahakikisha saraka safi ya kikao, lakini ni wazi kuwa ni ghali sana kwa seva. Kwa hivyo, kwenye mifumo ya uzalishaji, thamani chaguomsingi ya session.gc_divisor imewekwa kuwa 1000, ambayo ina maana kwamba utaratibu wa kukusanya taka utaendeshwa na uwezekano wa 1/1000. Ikiwa unajaribu mipangilio hii katika faili yako ya php.ini, unaweza kuona kwamba katika kesi iliyoelezwa hapo juu, wakati kivinjari kinafunga na kufuta vidakuzi vyake vyote, bado kuna vipindi vya zamani vilivyobaki kwenye saraka ya vikao kwa muda. Lakini hii haipaswi kukusumbua, kwa sababu ... kama ilivyoelezwa tayari, hii haiathiri kwa njia yoyote usalama wa utaratibu wetu.

Sasisho kutoka 2013-06-07

Inazuia hati kugandisha kwa sababu ya kufungwa kwa faili za kipindi

Maoni yaliibua suala la kufungia hati kwa wakati mmoja kwa sababu ya faili ya kikao kuzuiwa (chaguo la kuvutia zaidi ni kura ndefu).

Kuanza, ninaona kuwa shida hii haitegemei moja kwa moja mzigo wa seva au idadi ya watumiaji. Kwa kweli, maombi zaidi, polepole hati zinatekelezwa. Lakini hii ni utegemezi usio wa moja kwa moja. Tatizo linaonekana tu ndani ya kikao kimoja, wakati seva inapokea maombi kadhaa kwa niaba ya mtumiaji mmoja (kwa mfano, mmoja wao ni uchaguzi wa muda mrefu, na wengine ni maombi ya kawaida). Kila ombi linajaribu kufikia faili sawa ya kikao, na ikiwa ombi la awali halikufungua faili, basi inayofuata itasubiri kusubiri.

Ili kuweka kufuli kwa faili ya kikao kwa kiwango cha chini zaidi, inashauriwa sana kufunga kipindi kwa kupiga simu ya kitendakazi session_write_close() mara baada ya vitendo vyote vilivyo na vigeu vya kikao kukamilika. Kwa mazoezi, hii inamaanisha kuwa haupaswi kuhifadhi kila kitu kwenye anuwai za kikao na kuzifikia wakati wote wa utekelezaji wa hati. Na ikiwa unahitaji kuhifadhi data fulani ya kufanya kazi katika anuwai za kikao, basi zisome mara moja wakati kikao kinapoanza, zihifadhi katika anuwai za kawaida kwa matumizi ya baadaye na funga kikao (ikimaanisha kufunga kikao kwa kutumia session_write_close kazi, na sio kuiharibu kwa kutumia session_destroy. )

Katika mfano wetu, hii ina maana kwamba mara baada ya kufungua kikao, kuangalia maisha yake na kuwepo kwa mtumiaji aliyeidhinishwa, lazima tusome na kuhifadhi vigezo vyote vya ziada vya kikao vinavyohitajika na programu (kama zipo), kisha funga kikao kwa kutumia simu. kwa session_write_close() na kuendelea na utekelezaji wa hati, iwe ni kura ndefu au ombi la kawaida.

Kulinda vipindi dhidi ya matumizi yasiyoidhinishwa

Hebu fikiria hali hiyo. Mmoja wa watumiaji wako anapata Trojan ambayo huiba vidakuzi vya kivinjari (ambapo kipindi chetu huhifadhiwa) na kuituma kwa barua pepe maalum. Mshambulizi hupata kidakuzi na kukitumia kudanganya ombi kwa niaba ya mtumiaji wetu aliyeidhinishwa. Seva inakubali na kuchakata ombi hili kwa mafanikio kana kwamba limetoka kwa mtumiaji aliyeidhinishwa. Ikiwa uthibitishaji wa ziada wa anwani ya IP hautatekelezwa, shambulio kama hilo litasababisha udukuzi wa akaunti ya mtumiaji na matokeo yote yanayofuata.

Kwa nini hili liliwezekana? Ni wazi, kwa sababu jina na kitambulisho cha kikao huwa sawa kwa maisha yote ya kikao, na ukipokea data hii, unaweza kutuma maombi kwa urahisi kwa niaba ya mtumiaji mwingine (bila shaka, ndani ya maisha ya kipindi hiki). Hii inaweza kuwa sio aina ya kawaida ya shambulio, lakini kinadharia inaonekana kuwa inawezekana, haswa ikizingatiwa kuwa Trojan kama hiyo haihitaji hata haki za msimamizi ili kuiba vidakuzi vya kivinjari cha mtumiaji.

Unawezaje kujikinga na mashambulizi ya aina hii? Tena, ni wazi, kwa kuweka kikomo maisha ya kitambulisho cha kikao na kubadilisha kitambulisho mara kwa mara ndani ya kipindi sawa. Tunaweza pia kubadilisha jina la kikao kwa kufuta kabisa ya zamani na kuunda kikao kipya, kunakili vigezo vyote vya kikao kutoka kwa zamani ndani yake. Lakini hii haiathiri kiini cha mbinu, kwa hivyo kwa unyenyekevu tutajiwekea kikomo kwa kitambulisho cha kikao tu.

Ni wazi kwamba kadiri muda wa Kitambulisho wa kipindi kinavyopungua, ndivyo muda mshambulizi atalazimika kupata na kutumia vidakuzi kughushi ombi la mtumiaji. Kwa kweli, kitambulisho kipya kinapaswa kutumika kwa kila ombi, ambayo itapunguza uwezekano wa kutumia kikao cha mtu mwingine. Lakini tutazingatia kesi ya jumla wakati muda wa kuzaliwa upya wa kitambulisho cha kikao umewekwa kiholela.

(Tutaacha sehemu ya kanuni ambayo tayari imejadiliwa).

Kazi startSession($isUserActivity=true) (// Kitambulishi cha kipindi $idLifetime = 60; ... ikiwa ($idLifetime) ( // Ikiwa muda wa maisha wa kitambulisho cha kipindi umewekwa, // angalia muda uliopita tangu kipindi kuundwa au uundaji upya wa mwisho // (wakati wa ombi la mwisho wakati muda wa kuanza kutofautisha wa kikao ulisasishwa) ikiwa (isset($_SESSION["starttime"])) ( ikiwa ($t-$_SESSION["starttime"] >= $ idLifetime) ( // Muda wa maisha ya kitambulisho cha kipindi cha muda umekwisha // Tengeneza kitambulisho kipya session_regenerate_id(true); $_SESSION["starttime"] = $t ) ) vinginevyo ( // Tunafika hapa ikiwa kipindi kimeundwa hivi punde // Weka muda wa kuzalisha kitambulisho cha kipindi hadi wakati wa sasa $_SESSION["starttime"] = $t ) ) return true ;

Kwa hiyo, wakati wa kuunda kikao kipya (kinachotokea wakati mtumiaji anaingia kwa ufanisi), tunaweka wakati wa kuanza kwa kutofautiana kwa kikao, ambacho huhifadhi kwa ajili yetu wakati wa kizazi cha mwisho cha kitambulisho cha kikao, kwa thamani sawa na wakati wa sasa wa seva. Ifuatayo, katika kila ombi, tunaangalia ikiwa muda wa kutosha (idLifetime) umepita tangu kizazi cha mwisho cha kitambulisho, na ikiwa ni hivyo, tunatoa kipya. Kwa hivyo, ikiwa wakati wa maisha ya kitambulisho mshambuliaji aliyepokea kidakuzi cha mtumiaji aliyeidhinishwa hana muda wa kukitumia, ombi la uwongo litachukuliwa na seva kuwa halijaidhinishwa, na mvamizi atachukuliwa hadi kwenye ukurasa wa kuingia. .

Kumbuka: Kitambulisho kipya cha kipindi huingia kwenye kidakuzi cha kivinjari wakati kitendakazi cha session_regenerate_id() kinapoitwa, ambacho hutuma kidakuzi kipya, sawa na kitendakazi cha session_start(), kwa hivyo hatuhitaji kusasisha kidakuzi sisi wenyewe.

Ikiwa tunataka kufanya vikao vyetu kuwa salama iwezekanavyo, inatosha kuweka maisha ya kitambulisho kwa moja au hata kuondoa kazi ya session_regenerate_id() kwenye mabano na kuondoa hundi zote, ambayo itasababisha kuzaliwa upya kwa kitambulisho katika kila moja. ombi. (Sijajaribu athari za mbinu hii kwenye utendaji, na naweza kusema tu kwamba session_regenerate_id(true) kazi kimsingi hufanya vitendo 4 tu: kutoa kitambulisho kipya, kuunda kichwa na kuki ya kikao, kufuta ya zamani na kuunda. faili mpya ya kikao).

Upungufu wa sauti: Ikiwa Trojan itaonekana kuwa nzuri sana kwamba haitatuma vidakuzi kwa mshambulizi, lakini itapanga kutuma ombi bandia lililotayarishwa mapema mara tu inapopokea kidakuzi, njia iliyoelezewa hapo juu haitaweza kulinda dhidi ya vile. shambulio, kwa sababu kati ya wakati Trojan inapokea kuki na kutuma ombi la uwongo hakutakuwa na tofauti yoyote, na kuna uwezekano mkubwa kwamba kwa wakati huu kitambulisho cha kikao hakitafanywa upya.

Uwezekano wa kufanya kazi kwa wakati mmoja katika kivinjari kimoja kwa niaba ya watumiaji kadhaa

Kazi ya mwisho ambayo ningependa kuzingatia ni uwezo wa watumiaji kadhaa kufanya kazi wakati huo huo katika kivinjari kimoja. Kipengele hiki ni muhimu sana katika hatua ya majaribio, wakati unahitaji kuiga kazi ya wakati huo huo ya watumiaji, na inashauriwa kufanya hivyo kwenye kivinjari chako unachopenda, badala ya kutumia arsenal nzima inayopatikana au kufungua matukio kadhaa ya kivinjari katika hali fiche. .

Katika mifano yetu ya awali, hatukutaja kwa uwazi jina la kipindi, kwa hivyo jina chaguo-msingi la PHP (PHPSESSID) lilitumiwa. Hii ina maana kwamba vipindi vyote ambavyo tumeunda kufikia sasa vimetuma kidakuzi kwa kivinjari chini ya jina PHPSESSID. Kwa wazi, ikiwa jina la kuki daima ni sawa, basi hakuna njia ya kuandaa vikao viwili na jina moja ndani ya kivinjari sawa. Lakini ikiwa tungetumia jina la kipindi chetu kwa kila mtumiaji, tatizo lingetatuliwa. Hebu tufanye hivyo.

Kazi startSession($isUserActivity=true, $prefix=null) ( ... ikiwa (session_id()) itarudi kuwa kweli; // Ikiwa kiambishi awali cha mtumiaji kitapitishwa katika vigezo, // weka jina la kipindi cha kipekee ambacho kinajumuisha hii. kiambishi awali, // vinginevyo weka jina la kawaida kwa watumiaji wote (kwa mfano, MYPROJECT) session_name("MYPROJECT".($prefix ? "_".$prefix: "")); ikiwa (! session_start()) itarudi sivyo ... )

Sasa kilichobaki ni kuhakikisha kuwa hati ya kupiga simu inapitisha kiambishi awali cha kipekee kwa kila mtumiaji kwa kazi ya startSession(). Hii inaweza kufanywa, kwa mfano, kwa kupitisha kiambishi awali katika vigezo vya GET/POST vya kila ombi au kupitia kidakuzi cha ziada.

Hitimisho

Kwa kumalizia, nitatoa msimbo kamili wa mwisho wa kazi zetu kwa kufanya kazi na vikao vya PHP, ikiwa ni pamoja na kazi zote zilizojadiliwa hapo juu.

Function startSession($isUserActivity=true, $prefix=null) ( $sessionLifetime = 300; $idLifetime = 60; ikiwa (session_id()) itarudi kweli; session_name("MYPROJECT".($prefix ? "_".$prefix: "")); ini_set("session.cookie_lifetime", 0 if (! session_start()) rudisha sivyo; $t-$_SESSION["lastactivity"] >= $sessionLifetime) ( destroySession(); rudisha sivyo; ) vinginevyo ( if ($isUserActivity) $_SESSION["lastactivity"] = $t; ) ) ikiwa ($idLifetime ) ( ikiwa (isset($_SESSION["starttime"])) ( ikiwa ($t-$_SESSION["starttime"] >= $idLifetime) ( session_regenerate_id(true); $_SESSION["starttime"] = $t; ) ) else ( $_SESSION["starttime"] = $t; ) ) rudisha trueSession() ( if (session_id()) ( session_unset(); setcookie(session_name(), session_id(), time() -60* 60*24 kikao_haribu ();

Natumai nakala hii itaokoa muda kwa wale ambao hawajawahi kuzama sana kwenye utaratibu wa kikao, na kutoa ufahamu wa kutosha juu ya utaratibu huu kwa wale ambao wanaanza kufahamiana na PHP.