v13.39.0. Per le operazioni di base consulta Sessioni, per il caricamento automatico dei provider consulta Package auto-discovery.
extend riceve un handler, non uno Store
Il callback diSession::extend() restituisce un handler di salvataggio che implementa la SessionHandlerInterface di PHP. Non è un’API che restituisce direttamente uno Store che implementa Illuminate\Contracts\Session\Session o un Repository di cache.
SessionManager::callCustomCreator() passa il valore restituito dal callback a buildSession(), che lo avvolge in uno Store o in un EncryptedStore a seconda di session.encrypt. In quel momento applica anche il nome del cookie e session.serialization.
Nella normale elaborazione HTTP, il middleware StartSession gestisce l’avvio e il salvataggio della sessione. Per fornire un handler, il pacchetto non deve chiamare session_start() né session_set_save_handler().
Distinguere le parti del contratto di salvataggio
Per implementare un backend personalizzato, soddisfa i seguenti ruoli.
Poiché lo
Store si occupa di serializzazione e ripristino, l’handler non deve applicare di nuovo serialize() o json_encode() all’array di sessione. Anche con la cifratura attiva, salva così com’è la stringa elaborata da EncryptedStore.
Registrare solo la creazione in boot
L’esempio minimo seguente riutilizza ilCacheBasedSessionHandler integrato. Non implementa un nuovo protocollo di storage, ma mostra come registrare un driver personalizzato che usa uno store di cache con nome. Acme\SessionBridge\ corrisponde a src/ tramite il PSR-4 di Composer.
Prepara il provider in src/SessionBridgeServiceProvider.php.
Session::extend() ottiene il SessionManager e registra la creazione, ma a questo punto lo store di cache all’interno del callback non viene risolto. Lo storage viene creato solo quando il driver viene selezionato per la prima volta. Non eseguire verifiche di connessione né salvataggi di dati nel boot() del provider.
Se usi una tua implementazione di SessionHandlerInterface, sostituisci l’handler restituito dal callback. Arrivare fino a new Store(...) non corrisponde più al valore di ritorno atteso dal SessionManager.
- Carica il provider come un normale provider non differito.
- Completa la registrazione prima del primo utilizzo della sessione. Se un altro provider risolve il tuo driver prima, verifica anche l’ordine di caricamento.
- Usa un nome di driver specifico del pacchetto. Un
extend()con lo stesso nome sovrascrive la creazione, e registrando il nome di un driver integrato si ottiene la precedenza sull’implementazione integrata.
L’applicazione che usa il pacchetto sceglie in modo esplicito
L’utente modifica le chiavi corrispondenti del proprioconfig/session.php esistente. Le altre impostazioni restano invariate.
stores esistente di config/cache.php. L’esempio seguente usa la connessione Redis default. La configurazione della connessione Redis e il client necessario vanno preparati dall’applicazione.
createRedisDriver() del driver di sessione Redis integrato, aggiungere session.connection o session.prefix non viene recepito automaticamente da questo callback.
Questo callback non modifica né il Repository né la configurazione dello storage: usa lo store con nome così com’è. Anche lo store array di test condivide lo stesso spazio di salvataggio all’interno della stessa applicazione.
Il pacchetto non deve riscrivere incondizionatamente session.driver, il nome del cookie o il prefisso di cache globale dell’applicazione. Verifica con l’utente anche che lo spazio di salvataggio non sia condiviso con altri usi e che più server possano usare lo stesso storage.
Mantenere l’unità del TTL e il formato di salvataggio
Il costruttore diCacheBasedSessionHandler riceve la durata di conservazione in minuti. Poiché write() passa ogni volta $minutes * 60 al put() del Repository di cache, nell’esempio precedente il TTL si rinnova a ogni scrittura. gc() restituisce 0 e delega la scadenza alla cache.
La durata che StartSession passa al gc($lifetime) dell’handler è invece in secondi. Non implementare un salvataggio che usa direttamente il valore di session.lifetime come secondi.
Inoltre, le modifiche seguenti non si risolvono con un semplice cambio di nome nella configurazione.
Se un aggiornamento del pacchetto modifica questi elementi, valuta istruzioni per una nuova autenticazione, l’eventuale necessità di una migrazione e i deploy in cui convivono la versione vecchia e quella nuova. Come in Gestire la compatibilità tra versioni dei pacchetti, includi formato di salvataggio e chiavi di configurazione nella specifica pubblica da mantenere.
Uno Store già creato non viene sostituito solo cambiando la configurazione
Manager, la classe padre del SessionManager, conserva i driver creati per nome. Inoltre, SessionServiceProvider registra session.store come singleton.
forgetDrivers() non è nemmeno un’API per eliminare i dati di sessione. Ricreare lo Store durante una richiesta in corso causa incongruenze con i dati già letti o con altri riferimenti.
Anche il CacheManager di questo esempio conserva gli store con nome. Se ne modifichi la configurazione di connessione, non basta risolvere di nuovo soltanto il SessionManager.
Nei deploy che usano la cache della configurazione, ricostruisci la cache e riavvia anche i worker di lunga durata perché carichino il nuovo codice e la nuova configurazione. Il riavvio dell’applicazione e la migrazione dei dati salvati sono attività distinte.
Il salvataggio della sessione e il lock delle richieste sono separati
Implementare un handler personalizzato non basta a serializzare le richieste parallele sulla stessa sessione. Il blocco diStartSession usa i lock dello store di cache scelto con session.block_store, che non coincide necessariamente con lo storage della sessione stessa.
Se lo controlli con Route::post(...)->block() o simili, verifica separatamente uno store di cache che supporti i lock, la condivisione tra più server e i tempi di attesa e di mantenimento. Il pacchetto non deve attivare di sua iniziativa il blocco per l’intera applicazione.
Testare fino al salvataggio e alla rilettura
Nei pacchetti che usano Orchestra Testbench, carica il provider e prepara test che selezionino davvero il tuo driver. Ecco un esempio ditests/SessionDriverTest.php. La cache array di test non usa connessioni esterne.
array come storage condiviso in produzione.
Prima di pubblicare un handler personalizzato, aggiungi anche i seguenti controlli.
- Un ID non salvato o scaduto restituisce una stringa vuota
- La stringa salvata viene ripristinata senza modifiche e non è più recuperabile dopo l’eliminazione
- L’unità e il rinnovo del TTL, e la scadenza sul backend reale
- I fallimenti di lettura, scrittura ed eliminazione producono i valori di ritorno o le eccezioni stabiliti
- L’andata e ritorno con
session.encryptattivo e i formati di serializzazione supportati - Il solo caricamento del provider non accede allo storage e non sottrae la selezione ai driver integrati
- Se necessario, test HTTP che passano per il vero middleware
webe i cookie, e il lock delle richieste parallele
Pagine correlate
Sessioni
Lettura e scrittura della sessione, dati flash e rigenerazione dell’ID.
Implementazione interna di Manager
Creazione e conservazione dei driver personalizzati e delega al driver predefinito.
Store di cache personalizzati nei pacchetti
Suddivisione dei ruoli tra lo Store di cache usato come storage e il Repository, e contratto del TTL.
Ciclo di vita dei servizi di un pacchetto
Dipendenze conservate dai worker di lunga durata e isolamento dello stato.
Fonti primarie
- Documentazione ufficiale HTTP Session: driver personalizzati e blocco
- Documentazione ufficiale sullo sviluppo di pacchetti
- SessionManager: creazione personalizzata e costruzione dello Store
- Store: lettura, serializzazione, salvataggio e rigenerazione dell’ID
- CacheBasedSessionHandler: conversione del TTL e contratto di salvataggio
- CacheManager: store con nome e configurazione Redis
- Manager: extend, driver, forgetDrivers
- SessionServiceProvider: registrazione singleton del Manager e di session.store
- StartSession: salvataggio, GC e lock tramite cache
- CacheBasedSessionHandlerTest ufficiale: verifica di dati non salvati, TTL ed eliminazione