Computer finestre Internet

Sessioni. Descrizione dettagliata del funzionamento e spiegazione del meccanismo. Protezione dell'id di sessione nell'organizzazione PHP inurl guestbook php phpsessid

Sessioni in PHP o come vengono salvati i dati di un utente o cliente che è entrato nel sito durante la navigazione tra le pagine del sito senza troppe difficoltà. La lezione è molto importante. Rilevante per la creazione del 95% dei siti.

Cos'è la sessione in php

Le sessioni sono utilizzate per memorizzare dati temporanei (ad esempio, che l'utente ha inserito nel sito) durante la navigazione tra le pagine dello stesso sito. Quando si utilizzano le sessioni, i dati vengono salvati in file temporanei sul server.
Molto spesso, le sessioni (e anche i cookie) vengono utilizzate durante la creazione di negozi online, forum, bacheche, social network, blog e altre risorse. La comodità del sistema di sessione consiste nel memorizzare le informazioni temporanee dell'utente/cliente che ha effettuato l'accesso, i cui dati sono in accesso rapido per un certo tempo. La sessione ha una data di scadenza naturale - fino alla chiusura del browser. Se chiudi solo la pagina, quando apri il sito, i dati sull'utente / acquirente saranno ancora disponibili.

Logica di sessione

La sessione (o sessione) è un tipo di archiviazione temporanea dei dati. Ti avverto subito che vale la pena salvare una piccola quantità di dati. Ad esempio, il login e la password dell'utente che effettua il login o il suo numero di serie nel database.

Esempio di lavoro
1. L'utente inserisce un nome utente e una password ed entra nel sito
2. I dati con login e password vengono salvati nella sessione di una delle pagine del sito:

File index.php

Inizio_sessione (); // ogni file in cui si desidera utilizzare i dati di sessione deve contenere il comando "start session" all'inizio del codice

$ accesso = "amministratore";
$ password = "passa";
$ _SESSION ["accesso"] = $ accesso; // salva la variabile contenente il login
$ _SESSION ["password"] = $ password; // salva la variabile contenente la password

3. Quando si accede ad un'altra pagina del sito, saranno disponibili anche questi dati:

File esempio.php(o qualsiasi altra pagina)

Echo "Il tuo login" $ _ SESSIONE ["login"]; // mostrerà "Il tuo login è admin", anche se non abbiamo registrato dati su questa pagina!
Vedi, è semplice!

4. Se vuoi cancellare i dati della sessione, allora è sufficiente:

File esempio.php

Inizio_sessione (); // "riavvia la sessione"

Annulla impostazione ($ _ SESSIONE ["accesso"]); // ecco come la variabile è stata non registrata o "distrutta"
echo "Il tuo login" $ _ SESSIONE ["login"]; // mostrerà "Il tuo login". Dato che l'abbiamo distrutto nell'ultima riga, non ci sono nemmeno dati.

Session_destroy (); //distrugge la sessione. Tutti i dati incluso $ _SESSION ["password"] sono spariti. Quando richiesto, verrà visualizzato un errore
In generale, tale trasferimento è simile al metodo POST, ma non è più necessario scrivere molto codice non necessario e tutti i dati trasferiti da una pagina all'altra vengono archiviati in file temporanei sul server. Anche in questo caso, le sessioni dovrebbero contenere piccole quantità di dati, quindi sono adatte per memorizzare nome utente/password, carrello della spesa e altre piccole quantità.

Passare un valore o un array usando una sessione PHP

In una sessione è possibile scrivere non solo una stringa, ma anche un array di dati. Basta non esagerare con le dimensioni dell'array, poiché tutto ciò influirà sulle prestazioni e sullo spazio occupato sul server.

Usiamo di nuovo una determinata pagina iniziale index.php

Inizio_sessione ();

$ r = array ("uno", "due", "tre");

$ _SESSION ["arr"] = $ r;

Alla pagina in cui verrà visualizzato tutto
Abbiamo salvato i dati nella sessione e seguiamo il collegamento a un'altra pagina, dove verranno visualizzati tutti i dati.

Destinatario del file, pagina test.php dove apriamo l'array

Inizio_sessione ();
print_r ($ _ SESSIONE ["arr"]);
// produrrà
/*
Vettore
=> uno
=> due
=> tre
*/
?>
Potresti voler rispolverare una lezione su. In generale, tutto dovrebbe essere chiaro.

Altre funzioni per lavorare con le sessioni

session_unregister (stringa)- la sessione dimentica il valore della variabile globale specificata;
session_destroy()- la sessione viene distrutta (ad esempio, se l'utente ha lasciato il sistema premendo il pulsante di logout);
session_set_cookie_params (int durata [, percorso stringa [, dominio stringa]])- utilizzando questa funzione è possibile impostare la durata della sessione impostando unix_timestamp definendo l'ora di morte della sessione.

Elenco delle funzioni per lavorare con le sessioni (sessione) in php
session_cache_expire - Restituisce la scadenza della cache corrente
session_cache_limiter - Ottieni e/o imposta il limite corrente della cache
session_commit - un alias per session_write_close ()
session_decode - Decodifica i dati della sessione dalla stringa
session_destroy - Distrugge tutti i dati registrati per la sessione
session_encode - crittografa i dati della sessione corrente come una stringa
session_get_cookie_params - Ottieni i parametri dei cookie di sessione
session_id - ottiene e/o imposta l'id di sessione corrente
session_is_registered - determina se una variabile è registrata nella sessione
session_module_name - ottiene e/o installa il modulo della sessione corrente
session_name - ottiene e/o imposta il nome della sessione corrente
session_regenerate_id - Modifica l'ID della sessione corrente con quello appena generato
session_register - registra una o più variabili per la sessione corrente
session_save_path - ottiene e/o imposta il percorso per salvare la sessione corrente
session_set_cookie_params - imposta i parametri dei cookie di sessione
session_set_save_handler - imposta le funzioni di memorizzazione della sessione a livello di utente
session_start - inizializza i dati della sessione
session_unregister - Annulla la registrazione di una variabile dalla sessione corrente
session_unset - Rilascia tutte le variabili di sessione
session_write_close - Scrive i dati della sessione e la fine della sessione

Esempi di sessione

Il contatore delle visualizzazioni di pagina durante la sessione. Un chiaro esempio di lavoro. Tuttavia, dopo aver chiuso il browser, il conto alla rovescia ricomincerà.

Contatore di visite a una pagina in una sessione

// Un semplice esempio di utilizzo delle sessioni senza cookie.
nome_sessione ("prova");
inizio_sessione ();
$ _SESSIONE ["conta"] = @ $ _ SESSIONE ["conta"] + 1;
?>

Contatore


Nella sessione corrente con il browser, hai aperto questa pagina
tempo (i).
Chiudi il browser per azzerare questo contatore.
Clicca qui per aggiornare la pagina!
Ad ogni transizione, il contatore aumenterà di 1)

Grazie per l'attenzione! Buona fortuna per il tuo impegno!

Le sessioni sono in realtà molto semplici. Hai solo bisogno di capire a cosa servono e come sono organizzati. Rispondiamo prima alla prima domanda.
Forse sai che il server web non mantiene una connessione permanente con il client e ogni richiesta viene elaborata come una nuova, senza comunicazione con le precedenti.

Cioè, non puoi tenere traccia delle richieste dello stesso visitatore, né salvare variabili per lui tra visualizzazioni di pagine separate. Le sessioni sono state inventate per risolvere questi due problemi.
In realtà, le sessioni, in poche parole, sono un meccanismo che consente di identificare in modo univoco un browser e crea un file per questo browser sul server, che memorizza le variabili di sessione.

Non descriverò in dettaglio la necessità di un tale meccanismo. Si tratta di casi come il carrello della spesa in un negozio online, l'autorizzazione, nonché problemi non del tutto banali, come, ad esempio, la protezione di parti interattive del sito dallo spam.

In linea di principio, è abbastanza facile creare il proprio analogo delle sessioni, non così funzionale come il PHP integrato, ma sostanzialmente simile. Su cookie e database.

Quando richiediamo uno script, cerchiamo di vedere se un cookie è arrivato con un nome specifico. Se non ci sono cookie, impostalo e scrivi una nuova riga con i dati dell'utente nel database. Se ci sono cookie, allora leggiamo dal database. Con un'altra richiesta, cancelliamo i vecchi record dal database e ora abbiamo un meccanismo di sessione pronto. Non è affatto difficile. Ma ci sono alcune sfumature che rendono preferibile l'uso del meccanismo di sessione integrato.

Innanzitutto, è necessario identificare in qualche modo il browser. Per fare ciò, devi dargli un identificatore univoco e chiedergli di trasferirlo ad ogni richiesta. Mi vergogno ad ammettere, ma quando ho appreso per la prima volta delle sessioni, ho pensato che si trattasse di una sorta di meccanismo speciale, un nuovo modo di comunicazione tra il browser e il server: le "sessioni". Che l'identificatore di sessione sia passato in qualche modo speciale. Ma la delusione è stata crudele...

Le sessioni utilizzano metodi standard e ben noti di trasferimento dei dati. In realtà, semplicemente non ce ne sono altri.
L'identificatore è una variabile regolare. Per impostazione predefinita, il suo nome è PHPSESSID.
Il compito di PHP è di inviarlo al browser per restituirlo con la richiesta successiva. Dalla già citata sezione FAQ, si evince che una variabile può essere passata solo in due modi: nei cookie o nella richiesta POST/GET.
PHP utilizza entrambe le opzioni.

Due impostazioni in php.ini sono responsabili di questo:

session.use_cookies - se uguale a 1, PHP passa l'identificatore ai cookie, se 0 - quindi no.
session.use_trans_sid se uguale a 1, PHP lo passa aggiungendo URL e moduli, se 0 - quindi no.

Puoi modificare questi e altri parametri di sessione allo stesso modo delle altre impostazioni PHP: nel file php.ini, nonché utilizzando il comando ini_set() o nei file di configurazione del server web

Se è abilitato solo il primo, allora all'inizio della sessione (ad ogni chiamata) inizio_sessione()) i cookie sono impostati sul client. Il browser restituisce correttamente questo cookie ad ogni richiesta successiva e PHP ha un identificatore di sessione. I problemi iniziano se il browser non restituisce i cookie. In questo caso, senza ricevere cookie con un identificatore, PHP avvierà continuamente una nuova sessione e il meccanismo non funzionerà.

Se è abilitato solo il secondo, i cookie non vengono impostati. E quello che succede è, per il quale, in pratica, vale la pena usare il meccanismo di sessione integrato. Dopo che lo script ha svolto il suo lavoro e la pagina è completamente formata, PHP esamina tutto e aggiunge un ID di sessione a ciascun collegamento ea ciascun modulo. Sembra qualcosa del genere:

Indice

diventa

Indice

e un campo nascosto viene aggiunto ai moduli

In teoria, nelle nostre sessioni fatte in casa con te sui cookie e un database, puoi attribuire manualmente il trasferimento dell'ID a tutti i collegamenti da solo - e quindi le nostre sessioni funzioneranno indipendentemente dai cookie. Ma, vedi, è più piacevole quando qualcun altro fa questo lavoro? ;-)

Entrambe le opzioni sono abilitate per impostazione predefinita nelle versioni recenti di PHP. Come gestisce PHP questo caso? Il cuoco è sempre esposto. E i collegamenti vengono completati automaticamente solo se PHP non ha trovato cookie con un ID di sessione. Quando un utente visita il sito per la prima volta durante questa sessione, gli vengono posizionati dei cookie e i collegamenti vengono integrati. Alla richiesta successiva, se i cookie sono supportati, PHP vede i cookie e interrompe il completamento dei collegamenti. Se i cookie non funzionano, PHP continua ad aggiungere correttamente id ai collegamenti e la sessione non viene persa.
Gli utenti che utilizzano i cookie vedranno solo una volta un collegamento lungo con un ID.

Con il trasferimento dell'identificatore terminato. Ora resta da associare un file con dati sul lato server ad esso. PHP lo farà per noi. È sufficiente scrivere:

inizio_sessione ();
$ _SESSION ["test"] = "Ciao mondo!" ;

E PHP scriverà la variabile di test nel file associato a questa sessione.

C'è un punto molto importante qui.

Vettore $ _SESSIONE- speciale.
In esso, infatti, ci sono le variabili che vogliamo rendere disponibili nei vari script.
Per inserire una variabile in una sessione, è sufficiente assegnarla a un elemento dell'array $ _SESSION.
Per ricavarne il valore è sufficiente fare riferimento allo stesso elemento. Un esempio sarà di seguito.

Garbage collection - PHP è anche coinvolto nella rimozione di file obsoleti. Così come la codifica dei dati e un sacco di altre cose utili. Grazie a questa cura, lavorare con le sessioni è molto semplice.
Eccoci, infatti, e siamo giunti all'esempio del lavoro delle sedute.
L'esempio è molto piccolo:

inizio_sessione ();

eco "Hai aggiornato questa pagina"... $ _SESSION ["contatore"] ++. " una volta. " ;
eco "
aggiornare ";
?>

Controlliamo se abbiamo una variabile contatore nella sessione, in caso contrario, quindi la creiamo con un valore di 0, quindi emettiamo il suo valore e lo aumentiamo di uno. Il valore aumentato verrà scritto nella sessione e la volta successiva che lo script verrà chiamato, la variabile avrà il valore 1 e così via. Tutto è molto semplice.

Per avere accesso alle variabili di sessione su qualsiasi pagina del sito, devi scrivere SOLO UNA (!) Riga all'inizio di OGNI file in cui abbiamo bisogno di sessioni:

inizio_sessione ();

inizio_sessione ();
if ($ _SESSION ["autorizzato"]<> 1 ) {
intestazione ("Posizione: /auth.php");
Uscita;
}

Rimozione di variabili da una sessione. Se hai register_globals = off, scrivi semplicemente

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

Se no, allora qui vicino con esso devi scrivere:

session_unregister ("var");

È molto importante capire per cosa dovrebbero essere utilizzate le sessioni e cosa no.

Innanzitutto, ricorda che le sessioni possono essere utilizzate solo quando l'utente ne ha bisogno, per non ostacolarlo. Dopotutto, può sbarazzarsi dell'identificatore in qualsiasi momento!
Ad esempio, quando si verifica che una persona compili un modulo e non uno script, l'utente stesso è interessato al funzionamento della sessione, altrimenti non sarà in grado di inviare il modulo! Ma per limitare il numero di richieste allo script, la sessione non è più adatta: lo script dannoso semplicemente non restituirà l'identificatore.

In secondo luogo. È importante essere chiari sul fatto che una sessione è una sessione di lavoro con un sito, per come la intende una persona. È venuto, ha lavorato, ha chiuso il browser: la sessione è terminata. Come una sessione di film. Se vuoi vederne un altro, acquista un nuovo biglietto. Avvia una nuova sessione. C'è anche una spiegazione tecnica per questo. È garantito che il meccanismo di sessione funzioni solo fino alla chiusura del browser. Dopotutto, i cookie potrebbero non funzionare per il cliente e, in questo caso, ovviamente, tutti i collegamenti integrati con l'identificatore scompariranno alla chiusura.

Tuttavia, la sessione può essere persa senza chiudere il browser. A causa delle limitazioni discusse in questo articolo, il motore di sessione non è in grado di rilevare quando l'utente ha chiuso il browser. Per questo, viene utilizzato un timeout: un tempo predeterminato, dopo il quale consideriamo che l'utente abbia lasciato il sito. Per impostazione predefinita, questo parametro è 24 minuti.

Se desideri salvare le informazioni dell'utente per un periodo più lungo, utilizza i cookie e, se necessario, un database sul server. In particolare, ecco come funzionano tutti i più diffusi sistemi di autorizzazione:

All'identificazione dell'utente, la sessione inizia e in essa viene trasmesso il segno di autorizzazione.
- Se è necessario "ricordare" l'utente, gli viene impostato un cookie che lo identifica.
- La volta successiva che l'utente accede al sito, per effettuare il login, deve inserire una password, oppure il sistema stesso la riconosce dai cookie impostati in precedenza e la sessione inizia. Una nuova sessione, piuttosto che continuare una vecchia.

In terzo luogo, non vale la pena iniziare le sessioni indiscriminatamente, per tutti coloro che accedono al sito. Ciò creerà un carico completamente inutile. Non utilizzare sessioni per sciocchezze, ad esempio nei contatori. Ciò che le sessioni di chiamata spilogue sono, ovviamente, si basano sulle statistiche delle chiamate e non utilizzano un meccanismo di sessione simile a PHP.

Inoltre, prendiamo un motore di ricerca che indicizza il tuo sito. Se il robot di ricerca non supporta i cookie, PHP per impostazione predefinita consegnerà PHPSESSID ai collegamenti, il che potrebbe non essere molto piacevole per il motore di ricerca, che, secondo le indiscrezioni, non favorisce comunque i collegamenti dinamici, ma qui, in generale, con ogni chiamata - un nuovo indirizzo!

Se le sessioni vengono utilizzate per limitare l'accesso a una sezione chiusa del sito, allora tutto è solo un motore di ricerca e non deve essere indicizzato. Se devi mostrare la stessa pagina sia agli utenti autorizzati che a quelli non autorizzati, questo trucco ti aiuterà qui: avviare una sessione solo a coloro che hanno inserito la password o a coloro che hanno già avviato la sessione.

Per fare questo, invece di solo inizio_sessione() scriviamo:

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

quindi, avviamo la sessione solo a coloro che hanno inviato l'identificatore.
Di conseguenza, è necessario inviarlo all'utente per la prima volta - al momento dell'autorizzazione.

Se il nome e il capannone sono corretti, scrivi inizio_sessione() !

Gli errori più comuni che PHP fornisce quando si cerca di lavorare con le sessioni sono:
Due di loro,

Avviso: impossibile inviare cookie di sessione - intestazioni già inviate
Avviso: impossibile inviare il limitatore della cache di sessione - intestazioni già inviate

causato dallo stesso motivo, la soluzione è descritta in questo fatto

Avvertimento: open (/ tmp \ sess_SID, O_RDWR) non riuscito: nessun file o directory di questo tipo (2) in full_script_path sul numero di riga

prima sembrava

Avvertimento: Impossibile scrivere i dati della sessione (file). Si prega di verificare che l'impostazione corrente di session.save_path sia corretta (/ tmp) ,

se tradotto dall'inglese, spiega in dettaglio il problema: il percorso specificato in php.ini alla directory dove sono scritti i file di sessione non è disponibile. Questo errore è il più facile da correggere. Basta scrivere una directory che esiste ed è scrivibile, ad esempio,

session.save_path = c: \ windows \ temp

E non dimenticare di riavviare Apache dopo.

A quanto pare, l'intelligenza umana non ha limiti, e quindi devo spiegare:
il terzo messaggio di errore (la directory non può essere trovata) inevitabilmente porterà ai primi due, poiché il messaggio di errore viene inviato al browser e non è possibile utilizzare le intestazioni dopo di esso. Pertanto, non affrettarti a cercare una conclusione prematura, ma prima scrivi il percorso corretto!

Il prossimo problema più comune con le sessioni è la pesante eredità di register_globals. NON assegnare alle variabili di script gli stessi nomi degli indici dell'array $ _SESSION!

Con register_globals = on, i valori si sovrascriveranno a vicenda e ti confonderai.

Se non funziona, ma non vengono visualizzati nemmeno messaggi, aggiungi due righe all'inizio dello script che sono responsabili della visualizzazione di TUTTI gli errori sullo schermo: è del tutto possibile che ci siano errori, ma semplicemente non vedi loro.

ini_set ("display_errors", 1);
segnalazione_errore (E_ALL);

o vedere gli errori in error_log. In generale, l'argomento della visualizzazione dei messaggi di errore non rientra nell'ambito di questo articolo, quindi assicurati almeno di poterli vedere. Puoi leggere qualche dettaglio in più sulla risoluzione dei problemi in questa sezione.

Se sei sicuro che non ci siano errori, ma l'esempio dato non funziona comunque, allora è possibile che PHP non abiliti il ​​trasferimento dell'id tramite url, e i cookie non funzionano per qualche motivo.
Guarda cosa hai con i cookie.

In generale, se le tue sessioni "non funzionano", prova prima a trasferire manualmente l'identificatore di sessione, ovvero crea un collegamento e assegnagli un identificatore:

inizio_sessione ();
if (! isset ($ _ SESSION ["counter"])) $ _SESSION ["counter"] = 0;
eco "Hai aggiornato questa pagina"... $ _SESSION ["contatore"] ++. " una volta.

aggiornare ";
?>

Quando lo fai, assicurati che la direttiva session.use_only_cookies non sia abilitata, il che impedisce a PHP di accettare un ID di sessione se è stato passato attraverso un URL.

Se questo esempio non funziona, il problema è banale errori di battitura(metà dei "problemi" con le sessioni derivano da un nome di variabile errato), o in una versione troppo vecchia di PHP: il supporto per le sessioni è apparso nella versione 4.0 e l'array $ _SESSIONE- in 4.1 (Utilizzato in precedenza $ HTTP_SESSION_VARS).

Se funziona, il problema è nei cookie. Traccia: che tipo di cookie il server inserisce nel browser, se il browser lo restituisce. La ricerca è molto utile mentre si osservano gli scambi di intestazioni HTTP tra il browser e il server.

Spiegare come funzionano i cookie va oltre lo scopo di questo e troppo testo, ma assicurati almeno che il server invii i cookie con l'identificatore e che il browser ritorni. E mentre gli identificatori coincidono tra loro =)
L'impostazione dei cookie dovrebbe essere simile a

Set-Cookie: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6;

Set-Cookie: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; percorso = /

(se stai richiedendo uno script non dalla directory principale)
La risposta del server dovrebbe essere simile a

Cookie: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6

Cookie: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; b = b

se il browser restituisce cookie diversi dall'ID di sessione.

Se l'esempio da qui funziona, ma il tuo codice no, il problema ovviamente non è nelle sessioni, ma nell'algoritmo. Cerca dove hai perso la variabile, trasferisci l'esempio da qui passo dopo passo, esegui il debug del tuo script.

Un altro problema può sorgere se si utilizza il reindirizzamento dell'intestazione o la navigazione JavaScript.
Il fatto è che PHP aggiunge automaticamente l'identificatore di sessione solo ai collegamenti del modulo
, ma non lo fa per intestazioni, javascript, meta tag.

Pertanto, è necessario aggiungere manualmente l'identificatore, ad esempio in questo modo:

header ("Posizione: /script.php?". nome_sessione (). "=". ID_sessione ());

Inoltre, molto raro e del tutto poco chiaro da dove provenga, il problema è che l'impostazione session.save_handler ha un valore diverso da files. Se questo non è il caso, correggilo.

  • Oltre ai cookie, il meccanismo di sessione invia anche intestazioni che vietano la memorizzazione nella cache della pagina (lo stesso limitatore di cache). Per html, questo è corretto e necessario. Ma quando si tenta di inviare un file con uno script che verifica l'autorizzazione, Internet Explorer si rifiuta di scaricarlo. È a causa di questo titolo. Chiamata
    session_cache_limiter ("privato");
    deve risolvere il problema prima di iniziare la sessione.
  • Abbastanza stranamente, ma nell'array $ _SESSIONE non puoi usare indici numerici - $ _SESSIONE [1], $ _SESSIONE ["10"]- le sessioni non funzioneranno.
  • Da qualche parte tra 4.2 e 5.0 non è stato possibile impostare session.use_trans_sid con ini_set()... A partire da 5.0 è già possibile di nuovo.
  • Prima della versione 4.3.3 cookie PHP inviava cookie solo se la richiesta non conteneva un identificatore all'inizio della sessione. Ora i cookie vengono inviati ad ogni chiamata session_start

    Se hai altre domande o qualcosa non è chiaro, benvenuto nel nostro

Fin dall'inizio, tutti hanno accettato PHP con il botto, ma non appena hanno iniziato a creare progetti abbastanza grandi in questo linguaggio, gli sviluppatori hanno dovuto affrontare un nuovo problema: non esisteva il concetto di variabili globali in PHP! Cioè, uno script è stato eseguito, ha inviato la pagina generata al client e tutte le risorse utilizzate da questo script sono state distrutte. Per illustrare, diciamo che ci sono due pagine sullo stesso sito, index.php e dothings.php. Le fonti per queste pagine hanno questo aspetto:

index.php cose.php

Se esegui questi due script, nella prima pagina vedremo la scritta "Sono stato assegnato a index.php" e la seconda pagina sarà vuota.

Gli sviluppatori di siti Web, senza esitazione, hanno iniziato a utilizzare i cookie per memorizzare variabili globali sul lato client. Il processo era simile a questo: un utente arriva alla home page del sito, esegue alcune azioni e tutte le informazioni relative a questo utente, che potrebbero essere richieste in altre pagine del sito, verranno memorizzate nel suo browser nel modulo di un biscotto. Questo metodo presenta inconvenienti piuttosto seri, a causa dei quali molti sviluppatori hanno voltato le spalle a PHP contemporaneamente. Ad esempio, dobbiamo autorizzare un utente a consentirgli l'accesso a sezioni riservate (o solo sue) del sito. Dovrai inviare all'utente un cookie, che servirà come suo successivo identificatore sul sito. Questo approccio diventa molto macchinoso e scomodo non appena il sito inizia a raccogliere sempre più informazioni sul comportamento dell'utente, perché tutte le informazioni inviate all'utente dovrebbero preferibilmente essere codificate in modo che non possano essere falsificate. Più recentemente, falsificando un cookie, è stato possibile "posizionare" più di una chat e talvolta persino entrare nella posta di qualcun altro. Inoltre, ci sono ancora persone strane nel mondo il cui browser non supporta i cookie.

Non entrerò nelle questioni tecnologiche della struttura del meccanismo di sessione, ma descriverò solo come lavorare correttamente con le sessioni in PHP.

Come lavorare con le sessioni?

Se provi gli esempi dell'articolo (o i tuoi script) su qualsiasi hosting commerciale, non dovrebbero esserci problemi con il lavoro con le sessioni. Se configuri tu stesso il tuo server (che si tratti di un server reale o di un emulatore), potrebbero apparire errori con il seguente contenuto:

"Avviso: apertura (/var/state/php/sess_6f71d1dbb52fa88481e752af7f384db0, O_RDWR) non riuscita: nessun file o directory di questo tipo (2)".

Significa solo che il tuo PHP è configurato in modo errato. Puoi risolvere questo problema scrivendo il percorso corretto (nella directory esistente) per salvare le sessioni nel file php.ini e riavviare il server.

Qualsiasi script che utilizzerà variabili (dati) dalle sessioni dovrebbe contenere la seguente riga:

Inizio_sessione ();

Questo comando dice al server che la data pagina necessita di tutte le variabili che sono associate all'utente dato (browser). Il server prende queste variabili dal file e le rende disponibili. È molto importante aprire una sessione prima che qualsiasi dato venga inviato all'utente; in pratica, ciò significa che è consigliabile chiamare la funzione session_start() all'inizio della pagina, ad esempio:

Inizio_sessione (); ?> ... Per impostare la directory in cui verranno salvati i file di sessione, utilizzare la funzione session_save_path(): session_save_path ($ _ SERVER ["DOCUMENT_ROOT"]. "/ Session"); inizio_sessione ();

Una volta avviata la sessione, è possibile impostare le variabili globali. Quando si assegna un valore a qualsiasi campo nell'array $ _SESSION, una variabile con lo stesso nome viene registrata automaticamente come variabile di sessione. Questo array è disponibile su tutte le pagine che utilizzano la sessione. Ad esempio, analizziamo il programma:

index.php Tutto ok. La sessione è stata caricata! Andiamo, vediamo cosa c'è:

cose.php

Quando questi file vengono eseguiti in sequenza, il primo script "index.php" produrrà il seguente risultato:

Tutto ok. La sessione è stata caricata! Andiamo, vediamo cosa c'è:

E il secondo "dothings.php" è questo:

mi è stato chiesto su index.php

La variabile $ a è ora disponibile su tutte le pagine di questo sito che hanno avviato sessioni.

Altre funzioni e tecniche utili per lavorare con le sessioni:

  • annullato ($ _ SESSIONE ["a"])- la sessione "dimentica" il valore della variabile impostata dalla sessione;
  • session_destroy()- la sessione viene distrutta (ad esempio, se l'utente ha lasciato il sistema premendo il pulsante "esci");
  • session_set_cookie_params (int durata [, percorso stringa [, dominio stringa]])- utilizzando questa funzione, è possibile impostare la durata della "vita" della sessione impostando unix_timestamp definendo l'ora in cui la sessione "morirà". Per impostazione predefinita, la sessione "vive" finché il client non chiude la finestra del browser.
  • session_write_close()- registrare le variabili di sessione e chiuderla. Questo è necessario per aprire il sito in una nuova finestra, se la pagina sta effettuando una lunga elaborazione e ha bloccato il file di sessione per il tuo browser.

Esempi di

Passiamo ora all'applicazione pratica del meccanismo di sessione. Qui esamineremo un paio di esempi abbastanza semplici ma utili.

Autorizzazione dell'utente

Le domande sull'autorizzazione dell'utente che utilizzano le sessioni PHP vengono costantemente poste nelle conferenze di programmazione web. Il meccanismo per autorizzare gli utenti nel sistema che utilizzano le sessioni è abbastanza buono dal punto di vista della sicurezza (vedi sezione).

Il nostro esempio consisterà in tre file: index.php, allow.php e secretplace.php. Il file index.php contiene un modulo in cui l'utente inserirà il proprio nome utente e password. Questo modulo passerà i dati al file autorizza.php, che, in caso di autorizzazione riuscita, consentirà all'utente di accedere al file secretplace.php, altrimenti visualizzerà un messaggio di errore.

Esempi: index.php Inserisci la tua password

Login:
Parola d'ordine:


autorizzare.php page ... header ("Location: secretplace.php"); Uscita; )) // se qualcosa non andava, l'utente riceverà // un messaggio di errore. ?> Hai inserito una password errata!

secretplace.php Hey,, sei su una pagina segreta!!! :)

Sicurezza

Quindi, siamo in grado di trasferire un identificatore da una pagina (script PHP) a un'altra (fino alla prossima chiamata dal nostro sito), il che significa che possiamo distinguere tutti i visitatori del sito. Poiché l'identificatore di sessione è un numero molto grande (128 bit), non c'è praticamente alcuna possibilità che sia a forza bruta. Pertanto, l'attaccante ha le seguenti opzioni:

  • c'è un trojan sul computer dell'utente che ruba i numeri di sessione;
  • Un utente malintenzionato cattura il traffico tra il computer dell'utente e il server. Ovviamente esiste un protocollo SSL sicuro (crittografato), ma non tutti lo usano;
  • un vicino si è avvicinato al computer del nostro utente e ha rubato il numero di sessione.

Tali situazioni, basate sul fatto che qualcuno ruba qualcosa a qualcuno, in generale, non sono di competenza di un programmatore. Questo dovrebbe essere curato dagli amministratori e dagli utenti stessi.

Tuttavia, PHP può essere spesso ingannato. Diamo un'occhiata ai possibili punti di hacking nel programma di autorizzazione dell'utente:

  • File allow.php - un tentativo di indovinare una password utilizzando uno script di terze parti;
  • Il file secretplace.php è un tentativo di ingannare il programma inserendo i valori della variabile $log_user nella barra degli indirizzi del browser, ad esempio:
    "http://www.yoursite.ru/secretplace.php? loggato_utente = hacker"

Quindi, nel nostro programma, sono chiaramente visibili due "buchi", uno è piccolo e non particolarmente evidente, ma il secondo è semplicemente enorme, attraverso il quale la maggior parte degli hacker si arrampica dove non è necessario.

Come "riparare" la buca numero 1?

Non scriveremo tonnellate di codice per bloccare un indirizzo IP, ecc., ma controlleremo solo da dove proviene la richiesta, o meglio da quale pagina proviene la richiesta, se è una qualsiasi pagina del nostro sito, allora va tutto bene, ma in tutti gli altri casi non lo faremo entrare. Correggiamo il file autorizza.php:

autorizzare.php V2 page ... header ("Location: secretplace.php"); Uscita; )))?> Hai inserito una password errata!


Come sbarazzarsi del "buco" numero 2?

Supponiamo di avere un sito web dove ogni mortale può registrarsi per postare su un forum. Naturalmente nel forum alcuni utenti (admin, moderatori) hanno più possibilità di altri, ad esempio possono cancellare i messaggi di altri utenti. Memorizza il livello di accesso dell'utente nella sessione, nella variabile $ user_status, dove $ user_status = 10 corrisponde all'accesso completo al sistema. Un utente malintenzionato che arriva al sito deve solo registrarsi in modo regolare e quindi aggiungere nella barra degli indirizzi del browser ? stato_utente = 10... Quindi hai un nuovo amministratore sul tuo forum!

In linea di principio, qualsiasi variabile dello script può essere impostata tramite la riga dell'indirizzo, semplicemente aggiungendo allo script un punto interrogativo e il nome della variabile con il suo valore dopo l'indirizzo completo. Ripariamo il nostro codice per evitare questo:

secretplace.php V2 variabile unset ($ _ SESSION ["utente_registrato"]); // apre una sessione session_start (); / * non puoi semplicemente andare su questa pagina ... se il nome utente non è registrato, lo reindirizziamo alla pagina index.php per inserire nome utente e password ... qui infatti puoi fare molto, per esempio, ricorda l'IP dell'utente e, dopo i terzi tentativi di accesso ai file, bloccalo. * / if (! isset ($ _ SESSION ["logged_user"])) (header ("Location: index.php"); exit;)?> Hey,, sei su una pagina segreta!

Risultati

Il meccanismo di sessione è una caratteristica piuttosto interessante del linguaggio PHP. Le sessioni sono semplici, molto flessibili da usare. A proposito, ce n'è una, in alcuni punti documentata possibilità di sessioni PHP (disponibile dalla versione 4.0.3): nelle sessioni è possibile memorizzare non solo variabili, ma anche oggetti.

Esempi di

?>
// Inserimento automatico dei SID nei link. ini_set ("session.use_trans_sid", vero); inizio_sessione (); ?> Clicca qui!
Clicca qui !!



// Un esempio di come lavorare con le sessioni. inizio_sessione (); // Se il sito è appena stato visitato, azzera il contatore. if (! isset ($ _ SESSION ["count"])) $ _SESSION ["count"] = 0; // Aumenta il contatore nella sessione. $ _SESSION ["conta"] = $ _SESSIONE ["conta"] + 1; ?>

Contatore

tempo (i).
Chiudi il browser per azzerare il contatore.
"target =" _blank "> Apre una finestra del browser figlio.
// Un semplice esempio di utilizzo delle sessioni senza cookie. nome_sessione ("prova"); inizio_sessione (); $ _SESSIONE ["conta"] = @ $ _ SESSIONE ["conta"] + 1; ?>

Contatore

Nella sessione corrente con il browser, hai aperto questa paginatempo (i).
Chiudi il browser per azzerare questo contatore.
?"> Clicca qui per aggiornare la pagina!

Le sessioni sono un modo semplice per memorizzare le informazioni per i singoli utenti con un ID di sessione univoco. Questo può essere usato per mantenere lo stato tra le richieste di pagina. Gli ID di sessione vengono solitamente inviati al browser tramite un cookie di sessione e vengono utilizzati per recuperare i dati di sessione disponibili. L'assenza di un ID di sessione o di un cookie di sessione indica a PHP di creare una nuova sessione e generare un nuovo ID di sessione.

Le sessioni utilizzano una tecnologia semplice. Quando viene creata una sessione, PHP riceverà una sessione esistente utilizzando l'identificatore passato (di solito da un cookie di sessione) o, se non è stato passato nulla, verrà creata una nuova sessione. PHP popolerà il superglobale $ _SESSION con le informazioni sulla sessione dopo l'avvio della sessione. Quando PHP esce, serializzerà automaticamente il contenuto del superglobale $ _SESSION e lo invierà per l'archiviazione utilizzando un gestore di sessione per registrare la sessione.

Per impostazione predefinita, PHP utilizza un gestore di file interni per salvare le sessioni, che è impostato nella variabile INI session.save_handler. Questo gestore salva i dati sul server nella directory specificata nella direttiva di configurazione session.save_path.

Le sessioni possono essere avviate manualmente utilizzando la funzione inizio_sessione()... Se la direttiva session.auto_start è impostata su 1, la sessione verrà avviata automaticamente all'inizio della richiesta.

La sessione di solito termina quando PHP termina l'esecuzione dello script, ma può anche essere terminata manualmente utilizzando la funzione session_write_close().

Avvertimento

Attenzione

Commento:

Le sessioni che utilizzano file (per impostazione predefinita in PHP) bloccano il file di sessione immediatamente all'apertura di una sessione con la funzione inizio_sessione() o indirettamente specificando session.auto_start. Dopo il blocco, nessun altro script può accedere allo stesso file di sessione finché non viene chiuso o quando lo script termina o quando viene chiamata una funzione. session_write_close().

È molto probabile che questo sia un problema per i siti che utilizzano pesantemente AJAX e fanno più richieste simultanee. Il modo più semplice per risolvere questo problema è chiamare la funzione session_write_close() non appena sono state apportate tutte le modifiche richieste nella sessione, preferibilmente più vicino all'inizio dello script. È inoltre possibile utilizzare un altro meccanismo di sessione che supporti la concorrenza.

Non riesco a capire perché, ma ho provato tutte le risposte / google .. Non sono riuscito a trovare nulla. Ecco la situazione:

Codice host locale

Risultato:

Sequential session_id () tra le pagine dell'app e all'aggiornamento della pagina. $ _COOKIE ["PHPSESSID"] corrisponde a session_id ()

Server diretto

Inizio_sessione (); echo id_sessione (); print_r ($ _ COOKIE ["PHPSESSID"]);

Risultato:

session_id() cambia ad ogni richiesta, ricarica della pagina o visita a un'altra pagina. $ _COOKIE ["PHPSESSID"] è NULL / vuoto. Lo stesso codice viene utilizzato nella parte superiore della pagina. nessun altro contenuto.

Questo problema mi ha dato un vero mal di testa, che tipo di configurazione del server o errore potrebbe causare questo? Perché il cookie PHPSESSID è vuoto, credo che sia perché anche il session_id () associato viene reimpostato ad ogni richiesta?

Qualsiasi aiuto per favore ragazzi!

EDIT: ho creato un semplice file di test con 3 righe sul mio server remoto locale. Questo non è correlato al mio codice. $ _COOKIE ["PHPSESSID"] è ancora vuoto e ad ogni aggiornamento si verifica un nuovo session_id() sull'host reale.

error_reporting SET TO ALL Ottengo questo sull'host live:

Avviso: indice non definito: PHPSESSID in /home/vivaplug/public_html/dev/wp-content/plugins/test.php on line 5

Intestazioni di Google Chrome

LOCALHOST

URL della richiesta: http: //localhost/wp-content/plugins/test.php Metodo di richiesta: GET Codice di stato: 200 OK Intestazioni della richiesta visualizza sorgente Accetta: testo / html, applicazione / xhtml + xml, applicazione / xml; q = 0.9, image / webp, * / *; q = 0.8 Accetta-Codifica: gzip, deflate, sdch Accetta-Lingua: en-US, en; q = 0.8 Cache-Control: no-cache Connessione: keep-alive Cookie: PHPSESSID = 68b7m4arpsacks4aetgmd3rs93 Host: localhost Pragma: no-cache Agente utente: Mozilla / 5.0 (Windows NT 6.1) AppleWebKit / 537.36 (KHTML, come Gecko) Chrome / 30.0.1599.101 Safari / 537.36 Intestazioni di rispostavisualizza sorgente Cache-Control: no-store, no- cache, must-revalidate, post-check = 0, pre-check = 0 Connessione: Keep-Alive Content-Type: text / html Data: Tue, 05 Nov 2013 07:10:51 GMT Scade: Thu, 19 Nov 1981 08 : 52:00 GMT Keep-Alive: timeout = 5, max = 100 Pragma: no-cache Server: Apache / 2.4.4 (Win32) PHP / 5.4.16 Transfer-Encoding: chunked X-Powered-By: PHP / 5.4 .16

RIMUOVI SERVER

URL richiesta: http: //vivaplugins.com/dev/wp-content/plugins/test.php Metodo di richiesta: GET Codice di stato: 200 OK Intestazioni richiestavisualizza sorgente Accetta: testo / html, applicazione / xhtml + xml, applicazione / xml; q = 0.9, image / webp, * / *; q = 0.8 Accetta-Codifica: gzip, deflate, sdch Accetta-Lingua: en-US, en; q = 0.8 Cache-Control: max-age = 0 Connessione: keep- live Host: vivaplugins.com Agente utente: Mozilla / 5.0 (Windows NT 6.1) AppleWebKit / 537.36 (KHTML, come Gecko) Chrome / 30.0.1599.101 Safari / 537.36 Intestazioni di rispostavisualizza sorgente Età: 0 Cache-Control: no-store, no -cache, must-revalidate, post-check = 0, pre-check = 0 Content-Encoding: gzip Content-Type: text / html Data: Tue, 05 Nov 2013 07:07:49 GMT Pragma: no-cache Server: Hosting avanzato da http://www.unixy.net/varnish Transfer-Encoding: chunked Vary: Accept-Encoding Via: 1.1 vernice X-Cache: HIT X-Cache-Hits: 2 X-Cacheable: S X-Powered-By : PHP / 5.4.20 Vernice X: 1984840969 1984839805