Nette Documentation Preview

syntax
Seje
****

<div class=perex>

HTTP je protokol brez stanja, vendar mora skoraj vsaka aplikacija ohranjati stanje med zahtevami, npr. vsebino nakupovalne košarice. Za to se uporablja seja. Oglejmo si

- kako uporabljati seje
- kako se izogniti navzkrižju imen
- kako nastaviti potek veljavnosti

</div>

Pri uporabi sej vsak uporabnik prejme edinstven identifikator, imenovan ID seje, ki se posreduje v piškotku. Ta služi kot ključ do podatkov seje. Za razliko od piškotkov, ki so shranjeni na strani brskalnika, so podatki o seji shranjeni na strani strežnika.

Sejo konfiguriramo v [konfiguraciji |configuration#session], pri čemer je pomembna izbira časa izteka veljavnosti.

Sejo upravlja objekt [api:Nette\Http\Session], ki ga dobimo s posredovanjem z uporabo [vbrizgavanja odvisnosti |dependency-injection:passing-dependencies]. V predstavitvah preprosto pokličemo `$session = $this->getSession()`.

→ [Namestitev in zahteve |@home#Installation]


Začetek seje .[#toc-starting-session]
=====================================

Privzeto bo Nette samodejno zagnal sejo v trenutku, ko bomo začeli brati iz nje ali vanjo pisati podatke. Če želite sejo zagnati ročno, uporabite `$session->start()`.

PHP ob začetku seje pošlje glave HTTP, ki vplivajo na predpomnjenje, glejte [php:session_cache_limiter], in po možnosti piškotek z ID seje. Zato je treba sejo vedno začeti, preden brskalniku pošljemo kakršen koli izpis, sicer se vrže izjema. Če torej veste, da bo seja uporabljena med prikazovanjem strani, jo pred tem ročno zaženite, na primer v predstavitvenem programu.

V načinu za razvijalce Tracy zažene sejo, ker jo uporablja za prikaz preusmeritev in vrstic z zahtevami AJAX v vrstici Tracy.


Razdelek .[#toc-section]
========================

V čistem jeziku PHP je shramba podatkov seje izvedena kot polje, ki je dostopno prek globalne spremenljivke `$_SESSION`. Težava je v tem, da so aplikacije običajno sestavljene iz več neodvisnih delov, in če imajo vsi na voljo le eno isto polje, bo prej ali slej prišlo do kolizije imen.

Nette Framework rešuje težavo tako, da celoten prostor razdeli na dele (predmete [api:Nette\Http\SessionSection]). Vsaka enota nato uporablja svoj odsek z edinstvenim imenom in do trkov ne more priti.

Odsek dobimo od upravitelja sej:

```php
$section = $session->getSection('unique name');
```

V predstavitvenem programu je dovolj, da pokličemo `getSession()` s parametrom:

```php
// $this je Predavatelj
$section = $this->getSession('unique name');
```

Obstoj odseka lahko preverimo z metodo `$session->hasSection('unique name')`.

S samim odsekom je zelo enostavno delati z metodami `set()`, `get()` in `remove()`:

```php
// pisanje spremenljivk
$section->set('userName', 'franta');

// branje spremenljivke, vrne nič, če ne obstaja
echo $section->get('userName');

// odstranjevanje spremenljivke
$section->remove('userName');
```

Za pridobitev vseh spremenljivk iz razdelka je mogoče uporabiti cikel `foreach`:

```php
foreach ($section as $key => $val) {
	echo "$key = $val";
}
```


Kako nastaviti potek veljavnosti .[#toc-how-to-set-expiration]
--------------------------------------------------------------

Iztek veljavnosti lahko nastavite za posamezne odseke ali celo posamezne spremenljivke. Uporabnikova prijava lahko poteče čez 20 minut, vendar si lahko še vedno zapomnimo vsebino nakupovalne košarice.

```php
// razdelek poteče po 20 minutah.
$section->setExpiration('20 minutes');
```

Tretji parameter metode `set()` se uporablja za nastavitev izteka veljavnosti posameznih spremenljivk:

```php
// spremenljivka 'flash' poteče po 30 sekundah
$section->set('flash', $message, '30 seconds');
```

.[note]
Ne pozabite, da mora biti čas poteka celotne seje (glejte [konfiguracijo seje |configuration#session]) enak ali višji od časa, nastavljenega za posamezne odseke ali spremenljivke.

Preklic predhodno nastavljenega izteka je mogoče doseči z metodo `removeExpiration()`. Takojšen izbris celotnega odseka bo zagotovljen z metodo `remove()`.


Dogodki $onStart, $onBeforeWrite .[#toc-events-onstart-onbeforewrite]
---------------------------------------------------------------------

Objekt `Nette\Http\Session` ima [dogodka |nette:glossary#Events] `$onStart` in `$onBeforeWrite`, zato lahko dodate povratne klice, ki se kličejo po začetku seje ali preden se seja zapiše na disk in nato zaključi.

```php
$session->onBeforeWrite[] = function () {
	// zapisovanje podatkov v sejo
	$this->section->set('basket', $this->basket);
};
```


Upravljanje seje .[#toc-session-management]
===========================================

Pregled metod razreda `Nette\Http\Session` za upravljanje sej:

<div class=wiki-methods-brief>


start(): void .[method]
-----------------------
Začne sejo.


isStarted(): bool .[method]
---------------------------
Ali se je seja začela?


close(): void .[method]
-----------------------
Konča sejo. Seja se samodejno konča ob koncu scenarija.


destroy(): void .[method]
-------------------------
Konča in izbriše sejo.


exists(): bool .[method]
------------------------
Ali zahteva HTTP vsebuje piškotek z ID seje?


regenerateId(): void .[method]
------------------------------
Ustvari nov naključni ID seje. Podatki ostanejo nespremenjeni.


getId(): string .[method]
-------------------------
Vrne ID seje.

</div>


Konfiguracija .[#toc-configuration]
-----------------------------------

Seanso konfiguriramo v [konfiguraciji |configuration#session]. Če pišete aplikacijo, ki ne uporablja vsebnika DI, jo konfigurirajte s temi metodami. Poklicati jih je treba pred začetkom seje.

<div class=wiki-methods-brief>


setName(string $name): static .[method]
---------------------------------------
Nastavi ime piškotka, ki se uporablja za prenos ID seje. Privzeto ime je `PHPSESSID`. To je uporabno, če na istem spletnem mestu uporabljate več različnih aplikacij.


getName(): string .[method]
---------------------------
Vrne ime sejnega piškotka.


setOptions(array $options): static .[method]
--------------------------------------------
Konfigurira sejo. Mogoče je nastaviti vse [direktive seje |https://www.php.net/manual/en/session.configuration.php] PHP (v obliki camelCase, npr. namesto `session.save_path` napišite `savePath` ) in tudi [readAndClose |https://www.php.net/manual/en/function.session-start.php#refsect1-function.session-start-parameters].


setExpiration(?string $time): static .[method]
----------------------------------------------
Nastavi čas neaktivnosti, po katerem se seja izteče.


setCookieParameters(string $path, string $domain=null, bool $secure=null, string $samesite=null): static .[method]
------------------------------------------------------------------------------------------------------------------
Nastavi parametre za piškotke. Privzete vrednosti parametrov lahko spremenite v [konfiguraciji |configuration#Session cookie].


setSavePath(string $path): static .[method]
-------------------------------------------
Nastavi imenik, v katerem so shranjene datoteke sej.


setHandler(\SessionHandlerInterface $handler): static .[method]
---------------------------------------------------------------
Nastavi obdelava po meri, glejte [dokumentacijo PHP |https://www.php.net/manual/en/class.sessionhandlerinterface.php].

</div>


Najprej varnost .[#toc-safety-first]
====================================

Strežnik domneva, da komunicira z istim uporabnikom, dokler zahteve vsebujejo isti ID seje. Naloga varnostnih mehanizmov je zagotoviti, da to vedenje res deluje in da ni možnosti zamenjave ali kraje identifikatorja.

Zato ogrodje Nette Framework ustrezno konfigurira direktive PHP za prenos identifikatorja seje samo v piškotkih, preprečevanje dostopa iz JavaScripta in ignoriranje identifikatorjev v naslovu URL. Poleg tega v kritičnih trenutkih, kot je prijava uporabnika, ustvari nov identifikator seje.

Funkcija ini_set se uporablja za konfiguracijo PHP, vendar je njena uporaba pri nekaterih storitvah spletnega gostovanja žal prepovedana. Če je to vaš primer, poskusite prositi ponudnika gostovanja, da vam to funkcijo dovoli ali vsaj ustrezno konfigurira svoj strežnik. .[note]

Seje

HTTP je protokol brez stanja, vendar mora skoraj vsaka aplikacija ohranjati stanje med zahtevami, npr. vsebino nakupovalne košarice. Za to se uporablja seja. Oglejmo si

  • kako uporabljati seje
  • kako se izogniti navzkrižju imen
  • kako nastaviti potek veljavnosti

Pri uporabi sej vsak uporabnik prejme edinstven identifikator, imenovan ID seje, ki se posreduje v piškotku. Ta služi kot ključ do podatkov seje. Za razliko od piškotkov, ki so shranjeni na strani brskalnika, so podatki o seji shranjeni na strani strežnika.

Sejo konfiguriramo v konfiguraciji, pri čemer je pomembna izbira časa izteka veljavnosti.

Sejo upravlja objekt Nette\Http\Session, ki ga dobimo s posredovanjem z uporabo vbrizgavanja odvisnosti. V predstavitvah preprosto pokličemo $session = $this->getSession().

Namestitev in zahteve

Začetek seje

Privzeto bo Nette samodejno zagnal sejo v trenutku, ko bomo začeli brati iz nje ali vanjo pisati podatke. Če želite sejo zagnati ročno, uporabite $session->start().

PHP ob začetku seje pošlje glave HTTP, ki vplivajo na predpomnjenje, glejte session_cache_limiter, in po možnosti piškotek z ID seje. Zato je treba sejo vedno začeti, preden brskalniku pošljemo kakršen koli izpis, sicer se vrže izjema. Če torej veste, da bo seja uporabljena med prikazovanjem strani, jo pred tem ročno zaženite, na primer v predstavitvenem programu.

V načinu za razvijalce Tracy zažene sejo, ker jo uporablja za prikaz preusmeritev in vrstic z zahtevami AJAX v vrstici Tracy.

Razdelek

V čistem jeziku PHP je shramba podatkov seje izvedena kot polje, ki je dostopno prek globalne spremenljivke $_SESSION. Težava je v tem, da so aplikacije običajno sestavljene iz več neodvisnih delov, in če imajo vsi na voljo le eno isto polje, bo prej ali slej prišlo do kolizije imen.

Nette Framework rešuje težavo tako, da celoten prostor razdeli na dele (predmete Nette\Http\SessionSection). Vsaka enota nato uporablja svoj odsek z edinstvenim imenom in do trkov ne more priti.

Odsek dobimo od upravitelja sej:

$section = $session->getSection('unique name');

V predstavitvenem programu je dovolj, da pokličemo getSession() s parametrom:

// $this je Predavatelj
$section = $this->getSession('unique name');

Obstoj odseka lahko preverimo z metodo $session->hasSection('unique name').

S samim odsekom je zelo enostavno delati z metodami set(), get() in remove():

// pisanje spremenljivk
$section->set('userName', 'franta');

// branje spremenljivke, vrne nič, če ne obstaja
echo $section->get('userName');

// odstranjevanje spremenljivke
$section->remove('userName');

Za pridobitev vseh spremenljivk iz razdelka je mogoče uporabiti cikel foreach:

foreach ($section as $key => $val) {
	echo "$key = $val";
}

Kako nastaviti potek veljavnosti

Iztek veljavnosti lahko nastavite za posamezne odseke ali celo posamezne spremenljivke. Uporabnikova prijava lahko poteče čez 20 minut, vendar si lahko še vedno zapomnimo vsebino nakupovalne košarice.

// razdelek poteče po 20 minutah.
$section->setExpiration('20 minutes');

Tretji parameter metode set() se uporablja za nastavitev izteka veljavnosti posameznih spremenljivk:

// spremenljivka 'flash' poteče po 30 sekundah
$section->set('flash', $message, '30 seconds');

Ne pozabite, da mora biti čas poteka celotne seje (glejte konfiguracijo seje) enak ali višji od časa, nastavljenega za posamezne odseke ali spremenljivke.

Preklic predhodno nastavljenega izteka je mogoče doseči z metodo removeExpiration(). Takojšen izbris celotnega odseka bo zagotovljen z metodo remove().

Dogodki $onStart, $onBeforeWrite

Objekt Nette\Http\Session ima dogodka $onStart in $onBeforeWrite, zato lahko dodate povratne klice, ki se kličejo po začetku seje ali preden se seja zapiše na disk in nato zaključi.

$session->onBeforeWrite[] = function () {
	// zapisovanje podatkov v sejo
	$this->section->set('basket', $this->basket);
};

Upravljanje seje

Pregled metod razreda Nette\Http\Session za upravljanje sej:

start(): void

Začne sejo.

isStarted(): bool

Ali se je seja začela?

close(): void

Konča sejo. Seja se samodejno konča ob koncu scenarija.

destroy(): void

Konča in izbriše sejo.

exists(): bool

Ali zahteva HTTP vsebuje piškotek z ID seje?

regenerateId(): void

Ustvari nov naključni ID seje. Podatki ostanejo nespremenjeni.

getId(): string

Vrne ID seje.

Konfiguracija

Seanso konfiguriramo v konfiguraciji. Če pišete aplikacijo, ki ne uporablja vsebnika DI, jo konfigurirajte s temi metodami. Poklicati jih je treba pred začetkom seje.

setName(string $name): static

Nastavi ime piškotka, ki se uporablja za prenos ID seje. Privzeto ime je PHPSESSID. To je uporabno, če na istem spletnem mestu uporabljate več različnih aplikacij.

getName(): string

Vrne ime sejnega piškotka.

setOptions(array $options)static

Konfigurira sejo. Mogoče je nastaviti vse direktive seje PHP (v obliki camelCase, npr. namesto session.save_path napišite savePath ) in tudi readAndClose.

setExpiration(?string $time)static

Nastavi čas neaktivnosti, po katerem se seja izteče.

setCookieParameters(string $path, string $domain=null, bool $secure=null, string $samesite=null)static

Nastavi parametre za piškotke. Privzete vrednosti parametrov lahko spremenite v konfiguraciji.

setSavePath(string $path)static

Nastavi imenik, v katerem so shranjene datoteke sej.

setHandler(\SessionHandlerInterface $handler)static

Nastavi obdelava po meri, glejte dokumentacijo PHP.

Najprej varnost

Strežnik domneva, da komunicira z istim uporabnikom, dokler zahteve vsebujejo isti ID seje. Naloga varnostnih mehanizmov je zagotoviti, da to vedenje res deluje in da ni možnosti zamenjave ali kraje identifikatorja.

Zato ogrodje Nette Framework ustrezno konfigurira direktive PHP za prenos identifikatorja seje samo v piškotkih, preprečevanje dostopa iz JavaScripta in ignoriranje identifikatorjev v naslovu URL. Poleg tega v kritičnih trenutkih, kot je prijava uporabnika, ustvari nov identifikator seje.

Funkcija ini_set se uporablja za konfiguracijo PHP, vendar je njena uporaba pri nekaterih storitvah spletnega gostovanja žal prepovedana. Če je to vaš primer, poskusite prositi ponudnika gostovanja, da vam to funkcijo dovoli ali vsaj ustrezno konfigurira svoj strežnik.