la funzione session_start() di php
La funzione session_start() di PHP avvia una nuova sessione o riprende una sessione esistente per l’utente corrente. È una funzione fondamentale per gestire le sessioni nel contesto delle applicazioni web.
Funzionamento
- Inizializza o riprende una sessione: Se non esiste già una sessione,
session_start() ne crea una nuova e genera un identificativo univoco di sessione (session ID). Se invece esiste una sessione attiva per l’utente (identificata da un cookie o tramite URL), PHP riprende quella sessione.
- Gestione dell’identificativo di sessione (Session ID):
- Quando si avvia una nuova sessione, PHP genera un identificativo unico (ad esempio
abc123) che viene utilizzato per identificare i dati della sessione associati a quell’utente.
- L’ID della sessione viene inviato al client tramite un cookie (di default chiamato
PHPSESSID).
- Associazione a dati utente: Dopo aver avviato una sessione, PHP utilizza l’ID della sessione per associare i dati dell’utente ad un array superglobale chiamato
$_SESSION.
Esempio di utilizzo
php
// Avvia o riprende una sessione
session_start();
// Aggiunge un valore alla sessione
$_SESSION['username'] = 'utente123';
$_SESSION['role'] = 'admin';
// Recupera i dati della sessione
echo 'Benvenuto, ' . $_SESSION['username']; // Output: Benvenuto, utente123
?>
Dettagli tecnici
Quando usare session_start()
- Prima di accedere a
$_SESSION: Deve essere sempre chiamata prima di leggere o scrivere dati nell’array $_SESSION.
- All’inizio di uno script: Per garantire che la sessione sia inizializzata correttamente prima di accedere ai dati dell’utente.
Esempio errato (causerà un errore):
<?php
$_SESSION['username'] = 'utente123'; // Errore: session_start() non è stato chiamato
?>
Esempio corretto:
<?php
session_start(); // Avvia la sessione
$_SESSION['username'] = 'utente123'; // Ora funziona correttamente
?>
Errori comuni
- Sessione già avviata: Se
session_start() viene chiamata dopo che l’intestazione HTTP è già stata inviata, genera un errore. Errore tipico:
css
Copia codice
Warning: session_start(): Cannot send session cookie - headers already sent
Soluzione: Assicurarsi che session_start() sia chiamata all’inizio dello script, prima di qualsiasi output.
- Conflitto di sessioni: Utilizzare un nome specifico per la sessione con
session_name() per evitare conflitti in applicazioni condivise.
Parametri opzionali
A partire da PHP 7.0, session_start() accetta un array opzionale di opzioni:
session_start([
'cookie_lifetime' => 3600, // Durata del cookie in secondi
'read_and_close' => true, // Chiude la sessione subito dopo la lettura
]);
In sintesi la funzione session_start():
- Crea una nuova sessione o riprende una esistente.
- Gestisce l’identificativo di sessione (Session ID).
- Permette di associare dati persistenti all’utente attraverso l’array superglobale
$_SESSION.
Opzioni di Configurazione di PHP per le sessioni
Le sessioni PHP sono configurabili tramite il file php.ini o ini_set(). Ecco alcune opzioni comuni:
session.save_path: Percorso in cui sono memorizzati i file di sessione.
session.gc_maxlifetime: Durata massima dei dati di sessione in secondi.
session.cookie_secure: Garantisce che i cookie vengano inviati solo tramite HTTPS.
session.use_strict_mode: Impone una gestione rigorosa degli ID di sessione per migliorare la sicurezza.
PHP offre diverse configurazioni relative alla gestione delle sessioni, tutte personalizzabili tramite il file php.ini, direttive ini_set() o configurazioni specifiche in runtime. Di seguito sono descritte le principali impostazioni per la gestione delle sessioni.
1. session.save_path
Specifica la directory in cui vengono salvati i file di sessione lato server (ad esempio, file temporanei contenenti i dati delle sessioni).
2. session.name
Specifica il nome del cookie che contiene l’ID della sessione. Il valore predefinito è PHPSESSID.
3. session.gc_maxlifetime
Determina il tempo (in secondi) dopo il quale i dati di sessione inutilizzati vengono eliminati dal server durante il garbage collection.
4. session.gc_probability e session.gc_divisor
Definiscono la probabilità che il garbage collection delle sessioni venga eseguito.
5. session.cookie_lifetime
Imposta la durata del cookie di sessione sul client (browser). Se è 0, il cookie scade quando il browser viene chiuso.
6. session.cookie_path
Specifica il percorso in cui il cookie di sessione è valido sul dominio.
7. session.cookie_domain
Definisce il dominio per cui il cookie di sessione è valido.
8. session.cookie_secure
Imposta se il cookie di sessione deve essere trasmesso solo su connessioni HTTPS.
9. session.cookie_httponly
Impedisce l’accesso al cookie di sessione tramite JavaScript (protezione contro attacchi XSS).
10. session.use_cookies
Determina se PHP utilizza i cookie per memorizzare l’ID della sessione.
- Valore predefinito:
1 (Attivo).
- Esempio:
session.use_cookies = 1
11. session.use_only_cookies
Forza PHP a utilizzare solo cookie per l’ID di sessione, disabilitando il passaggio di ID tramite URL (per evitare attacchi session fixation).
12. session.use_trans_sid
Permette di aggiungere automaticamente l’ID della sessione agli URL, se i cookie sono disabilitati. Questa impostazione è deprecata per motivi di sicurezza.
13. session.sid_length
Specifica la lunghezza del session ID (da 22 a 256 caratteri).
- Valore predefinito:
32.
- Esempio:
session.sid_length = 48
14. session.sid_bits_per_character
Definisce il numero di bit usati per ogni carattere nel session ID (da 4 a 6).
Modifica delle configurazioni a runtime
È possibile modificare alcune delle configurazioni di sessione direttamente nello script PHP usando la funzione ini_set().
Esempio:
<?php
ini_set('session.gc_maxlifetime', 3600); // Sessione valida per 1 ora
ini_set('session.cookie_secure', 1); // Forza HTTPS
ini_set('session.cookie_httponly', 1); // Blocca accesso JavaScript ai cookie
session_start();
?>
Controllo delle configurazioni correnti
Puoi visualizzare le impostazioni attuali relative alle sessioni utilizzando la funzione phpinfo() o ini_get().
Esempio:
<?php
echo ini_get('session.gc_maxlifetime'); // Visualizza il valore attuale
phpinfo(); // Mostra tutte le configurazioni correnti
?>
Come funziona la gestione delle sessioni nel web server integrato
- Gestione standard:
- Il server incorporato rispetta le impostazioni di sessione definite nel file
php.ini o quelle modificate tramite ini_set() nello script.
- I file di sessione vengono salvati nella directory specificata da
session.save_path.
- Persistenza delle sessioni:
- Le sessioni vengono mantenute tra le richieste HTTP, a patto che il server sia in esecuzione e il client invii il cookie con l’ID di sessione (ad esempio, il cookie
PHPSESSID).
- Nessuna configurazione aggiuntiva:
- Il built-in server di PHP è progettato per eseguire applicazioni PHP in modo semplice e gestisce automaticamente le funzionalità di base come le sessioni.
Esempio di utilizzo delle sessioni con il built-in server
Script PHP con gestione della sessione
Crea un file chiamato session_example.php:
<?php
// Avvia la sessione
session_start();
// Incrementa un contatore nella sessione
if (isset($_SESSION['counter'])) {
$_SESSION['counter']++;
} else {
$_SESSION['counter'] = 1;
}
// Mostra il contatore
echo "Hai visitato questa pagina {$_SESSION['counter']} volte.";
// Link per resettare la sessione
echo '<br><a href="session_example.php?reset=true">Resetta sessione</a>';
// Gestisce il reset della sessione
if (isset($_GET['reset']) && $_GET['reset'] === 'true') {
session_destroy();
echo '<br>Sessione resettata.';
}
?>
Avvia il web server integrato
Esegui il server nella directory in cui si trova il file:
php -S localhost:8000
Poi visita l’indirizzo: http://localhost:8000/session_example.php.
- Ogni volta che ricarichi la pagina, il contatore (
$_SESSION['counter']) aumenta.
- Quando clicchi sul link “Resetta sessione”, la sessione viene distrutta.
Limitazioni del PHP Built-in Web Server
- Uso per sviluppo:
- Il web server integrato è progettato esclusivamente per lo sviluppo e il testing, non per ambienti di produzione. Non è ottimizzato per gestire molte richieste simultanee o per garantire la sicurezza necessaria in produzione.
- Garbage collection delle sessioni:
- Il built-in server si comporta come gli altri ambienti PHP per il garbage collection delle sessioni, basandosi sulle configurazioni di
session.gc_probability e session.gc_divisor.
- Concorrenza:
- Se hai più richieste concorrenti (ad esempio tramite AJAX), la gestione della sessione può causare blocchi temporanei poiché PHP blocca il file di sessione fino a quando la richiesta corrente non è terminata.
Dove vengono salvati i file di sessione?
Con la configurazione di default i file di sessione vengono salvati nella directory specificata dalla direttiva session.save_path. Se non è configurata, PHP utilizza la directory predefinita del sistema (ad esempio, /tmp su Unix/Linux).
Puoi verificare la directory con il seguente codice:
<?php
echo session_save_path();
?>
Gestori Personalizzati di Sessione
PHP consente agli sviluppatori di definire gestori personalizzati per memorizzare i dati di sessione in archivi alternativi come database o cookie.
Atri metodi di memorizzare le sessioni: le sessioni salvate in cookie criptati, le sessioni salvate su database
PHP Core è in grado di gestire metodi alternativi per memorizzare le sessioni, come salvarle in cookie criptati o in un database, senza bisogno di librerie esterne. Tuttavia, ciò richiede la personalizzazione delle funzionalità di gestione delle sessioni fornite da PHP, utilizzando le funzioni integrate per modificare il comportamento predefinito.
1. Gestione delle sessioni in cookie criptati
PHP permette di gestire le sessioni salvandole direttamente nei cookie del browser anziché nel filesystem del server. Per farlo, puoi usare il gestore di sessione personalizzato tramite la funzione session_set_save_handler().
Esempio di sessioni salvate nei cookie criptati
<?php
session_set_save_handler(
'open',
'close',
'read',
'write',
'destroy',
'gc'
);
// Funzione per criptare i dati
function encrypt_data($data) {
$key = 'my-secret-key'; // Usa una chiave sicura
return base64_encode(openssl_encrypt($data, 'aes-256-cbc', $key, 0, str_repeat('0', 16)));
}
// Funzione per decriptare i dati
function decrypt_data($data) {
$key = 'my-secret-key';
return openssl_decrypt(base64_decode($data), 'aes-256-cbc', $key, 0, str_repeat('0', 16));
}
// Funzione per leggere la sessione
function read($session_id) {
if (isset($_COOKIE[$session_id])) {
return decrypt_data($_COOKIE[$session_id]);
}
return '';
}
// Funzione per scrivere nella sessione
function write($session_id, $data) {
$encrypted_data = encrypt_data($data);
setcookie($session_id, $encrypted_data, time() + 3600, "/");
return true;
}
// Altre funzioni richieste (open, close, destroy, gc)
function open() {
return true;
}
function close() {
return true;
}
function destroy($session_id) {
setcookie($session_id, '', time() - 3600, "/");
return true;
}
function gc($maxlifetime) {
return true; // Nessuna gestione necessaria per i cookie
}
// Avvio della sessione
session_start();
$_SESSION['username'] = 'utente123';
echo 'Benvenuto, ' . $_SESSION['username'];
?>
Cosa fa il codice:
- I dati di sessione vengono salvati nel cookie del browser, criptati con AES-256.
- I cookie sono sicuri e non leggibili dall’utente.
- Non è richiesto l’uso di file lato server per memorizzare le sessioni.
2. Gestione delle sessioni salvate in un database
Anche per memorizzare le sessioni in un database, puoi utilizzare session_set_save_handler() per definire un gestore di sessioni personalizzato. In questo caso, i dati di sessione sono salvati in una tabella del database.
Esempio di sessioni salvate su database
Tabella MySQL per memorizzare le sessioni:
CREATE TABLE sessions (
session_id VARCHAR(255) NOT NULL PRIMARY KEY,
session_data TEXT NOT NULL,
session_expiry INT NOT NULL
);
Script PHP per gestire le sessioni:
<?php
session_set_save_handler(
'open',
'close',
'read',
'write',
'destroy',
'gc'
);
function open() {
$GLOBALS['db'] = new PDO('mysql:host=localhost;dbname=test', 'root', '');
return true;
}
function close() {
$GLOBALS['db'] = null;
return true;
}
function read($session_id) {
$stmt = $GLOBALS['db']->prepare('SELECT session_data FROM sessions WHERE session_id = :session_id AND session_expiry > :time');
$stmt->execute([
':session_id' => $session_id,
':time' => time()
]);
return $stmt->fetchColumn() ?: '';
}
function write($session_id, $data) {
$expiry = time() + ini_get('session.gc_maxlifetime');
$stmt = $GLOBALS['db']->prepare('REPLACE INTO sessions (session_id, session_data, session_expiry) VALUES (:session_id, :session_data, :session_expiry)');
return $stmt->execute([
':session_id' => $session_id,
':session_data' => $data,
':session_expiry' => $expiry
]);
}
function destroy($session_id) {
$stmt = $GLOBALS['db']->prepare('DELETE FROM sessions WHERE session_id = :session_id');
return $stmt->execute([':session_id' => $session_id]);
}
function gc($maxlifetime) {
$stmt = $GLOBALS['db']->prepare('DELETE FROM sessions WHERE session_expiry < :time');
return $stmt->execute([':time' => time()]);
}
// Avvio della sessione
session_start();
$_SESSION['username'] = 'utente123';
echo 'Benvenuto, ' . $_SESSION['username'];
?>
Cosa fa il codice:
- Salva i dati di sessione in un database MySQL, PostgreSQL o simile.
- Garantisce la persistenza dei dati anche in caso di riavvio del server PHP.
Considerazioni
- Cookie criptati:
- Vantaggi: Nessuna necessità di archiviazione lato server.
- Svantaggi: Dimensione limitata (max 4 KB) e possibili problemi di sincronizzazione in browser con politiche sui cookie.
- Database:
- Vantaggi: Scalabilità, persistenza dei dati su più server e capacità di analisi delle sessioni.
- Svantaggi: Maggiore complessità e potenziale overhead sul database.
- Implementazione nativa:
- PHP fornisce tutti gli strumenti per gestire questi approcci senza librerie esterne.
- L’uso di funzioni come
session_set_save_handler() permette di personalizzare completamente il comportamento delle sessioni.
Scrittura dei dati in Sessione
La scrittura dei dati in sessione non avviene immediatamente quando valorizzi la variabile superglobale $_SESSION, ma al termine dello script, nel momento in cui PHP chiude la sessione e salva i dati.
Quando avviene la scrittura in sessione
- Quando modifichi
$_SESSION durante l’esecuzione di uno script:
$_SESSION['key'] = 'value';
- Il dato viene aggiornato solo nella copia locale di
$_SESSION, che risiede in memoria (RAM) mentre lo script è in esecuzione.
- Salvataggio dei dati:
- PHP salva i dati di sessione nel percorso configurato (es. filesystem, database, ecc.) alla fine dello script, durante la fase di shutdown, dopo che tutte le operazioni sono state completate.
- Questo avviene automaticamente grazie alla funzione
session_write_close(), che PHP chiama implicitamente quando lo script termina, a meno che non venga chiamata manualmente prima.
Esempio per chiarire
Codice PHP:
<?php
session_start();
// Modifica il valore in $_SESSION
$_SESSION['username'] = 'utente123';
// Legge subito il valore modificato
echo "Username in sessione: " . $_SESSION['username'];
// Simula un'operazione manuale di salvataggio e chiusura
session_write_close();
// Prova a modificare la sessione dopo averla chiusa
$_SESSION['username'] = 'altro_utente';
?>
- Quando esegui:
$_SESSION['username'] = 'utente123';
- Il dato è aggiornato in
$_SESSION (memoria locale).
- La sessione viene salvata in modo definitivo quando PHP chiama
session_write_close() (o implicitamente al termine dello script).
- Se provi a modificare
$_SESSION dopo aver chiuso la sessione con session_write_close(), le modifiche non saranno salvate, perché il salvataggio avviene solo fino al momento della chiusura.
Funzioni correlate
session_write_close():
- Forza il salvataggio dei dati di sessione e chiude la sessione, rendendo i dati disponibili ad altre richieste.
- Esempio:
session_write_close();
session_abort():
- Annulla le modifiche fatte a
$_SESSION durante lo script, lasciando i dati della sessione invariati rispetto allo stato iniziale.
- Comportamento al termine dello script:
- PHP chiama automaticamente
session_write_close() alla fine dello script, garantendo che tutte le modifiche siano salvate.
Il dato in $_SESSION viene salvato in sessione (persistenza) al termine dello script o quando viene chiamata esplicitamente la funzione session_write_close(). La semplice assegnazione di un valore a $_SESSION aggiorna la variabile superglobale solo in memoria fino a quel momento.
Trappole Comuni e Best Practices
- Chiama sempre
session_start() prima di modificare $_SESSION.
- Usa
session_regenerate_id() per prevenire attacchi di session fixation.
- Proteggi le tue sessioni abilitando
session.cookie_secure e session.cookie_httponly.