Naar hoofdinhoud gaan
Wanneer je vanuit een package een eigen opslaglocatie voor sessies wilt aanbieden, scheid je het registreren van de opslag van de selectie door de applicatie. Alleen het installeren van de package mag niet veranderen waar de inlogstatus wordt opgeslagen: ontwerp het zo dat gebruikers het pas inschakelen nadat ze de impact op bestaande sessies hebben beoordeeld. Deze pagina is gecontroleerd aan de hand van de officiële broncode van Laravel Framework v13.39.0. Zie Sessies voor de basisbediening en Package discovery voor het automatisch laden van providers.

extend ontvangt een handler, geen Store

De callback van Session::extend() retourneert een opslaghandler die de PHP-SessionHandlerInterface implementeert. Het is geen API die rechtstreeks een Store retourneert die Illuminate\Contracts\Session\Session implementeert, of een cache-Repository. SessionManager::callCustomCreator() geeft de retourwaarde van de callback door aan buildSession(), dat deze afhankelijk van session.encrypt in een Store of EncryptedStore verpakt. Daarbij worden ook de cookienaam en session.serialization toegepast. Bij normale HTTP-verwerking beheert de middleware StartSession het starten en opslaan van de sessie. Om een handler aan te bieden hoeft de package session_start() of session_set_save_handler() niet aan te roepen.

Bekijk het opslagcontract per onderdeel

Wanneer je een eigen backend implementeert, vervul je de volgende rollen. Omdat de Store verantwoordelijk is voor serialisatie en herstel, pas je in de handler niet nogmaals serialize() of json_encode() toe op de sessie-array. Ook als versleuteling is ingeschakeld, sla je de door EncryptedStore verwerkte string ongewijzigd op.
Maak onderscheid tussen ontbrekende data en een storing in de backend. De onderzochte Store::readFromHandler() behandelt een leeg leesresultaat of false als een lege sessie. Bovendien controleert Store::save() de retourwaarde van write() van de handler niet.Moet je package storingen altijd als exceptions behandelen, leg dat beleid dan expliciet vast en test het: slik exceptions van de opslag niet in, en detecteer bij backends die false retourneren dit in de handler en zet het om in een exception. Laravel probeert het niet per se automatisch opnieuw en meldt een mislukte opslag niet per se.

Registreer in boot alleen het aanmaken

Het volgende minimale voorbeeld hergebruikt de ingebouwde CacheBasedSessionHandler. Het implementeert geen nieuw opslagprotocol, maar laat zien hoe je een eigen driver registreert die een benoemde cachestore gebruikt. Acme\SessionBridge\ is via Composer-PSR-4 gekoppeld aan src/. Maak de provider aan in src/SessionBridgeServiceProvider.php.
Session::extend() haalt de SessionManager op en registreert het aanmaken, maar de cachestore in de callback wordt op dat moment nog niet geresolved. De opslag wordt pas aangemaakt wanneer de driver voor het eerst wordt gekozen. Voer in de boot() van de provider geen verbindingscontroles of dataopslag uit. Gebruik je een eigen implementatie van SessionHandlerInterface, vervang dan de handler die de callback retourneert. Ga je zo ver dat je new Store(...) aanmaakt, dan past dat niet meer bij de retourwaarde die de SessionManager verwacht.
  • Laad de provider als een gewone, niet-uitgestelde provider.
  • Rond de registratie af voordat de sessie voor het eerst wordt gebruikt. Als een andere provider je driver eerder resolvet, controleer dan ook de laadvolgorde.
  • Gebruik een packagespecifieke drivernaam. Een extend() met dezelfde naam overschrijft het aanmaken, en wie een ingebouwde drivernaam registreert, krijgt voorrang op de ingebouwde implementatie.

De gebruikende applicatie kiest expliciet

De gebruiker past de betreffende keys in de bestaande config/session.php aan. De overige instellingen blijven staan.
Voeg voor de opslag een benoemde store toe aan de bestaande stores-array in config/cache.php. Het volgende voorbeeld gebruikt de Redis-verbinding default. De Redis-verbindingsinstellingen en de benodigde client regelt de applicatie zelf.
De verbinding en prefix in dit voorbeeld worden bepaald door de configuratie van de cachestore. Omdat createRedisDriver() van de ingebouwde Redis-sessiedriver niet wordt doorlopen, neemt deze callback session.connection of session.prefix niet automatisch over als je die toevoegt. Deze callback wijzigt de Repository en de opslagconfiguratie niet, maar gebruikt de benoemde store zoals die is. Ook de array-store voor tests deelt binnen dezelfde applicatie dezelfde opslagruimte. Laat de package session.driver, de cookienaam of de applicatiebrede cacheprefix niet onvoorwaardelijk overschrijven. Stem ook met de gebruiker af dat de opslagruimte niet met andere toepassingen wordt gedeeld en dat meerdere servers dezelfde opslag kunnen gebruiken.
Is je enige doel gewone opslag in Redis of een database, begin dan met de ingebouwde sessiedrivers. Een eigen driver is een uitbreidingspunt voor situaties waarin een nieuwe opslaglocatie of aanvullende opslagregels nodig zijn.

Behoud de TTL-eenheid en het opslagformaat

De constructor van CacheBasedSessionHandler ontvangt de bewaarduur in minuten. Omdat write() telkens $minutes * 60 doorgeeft aan put() van de cache-Repository, wordt de TTL in het voorbeeld hierboven bij elke schrijfactie vernieuwd. gc() retourneert 0 en laat het verlopen over aan de cache. De duur die StartSession aan gc($lifetime) van de handler doorgeeft, is daarentegen in seconden. Implementeer geen opslag die de waarde van session.lifetime rechtstreeks als seconden gebruikt. Daarnaast zijn de volgende wijzigingen niet af te doen met alleen een andere instellingsnaam. Verandert een package-update een van deze zaken, overweeg dan instructies voor opnieuw inloggen, of er een migratie nodig is, en deployments waarin oude en nieuwe versies naast elkaar draaien. Net als bij Versiecompatibiliteit van packages beheren horen het opslagformaat en de configuratiekeys bij de publieke specificatie die je onderhoudt.

Een aangemaakte Store wordt niet vervangen door alleen de configuratie te wijzigen

Manager, de bovenliggende klasse van de SessionManager, houdt aangemaakte drivers per naam vast. Daarnaast registreert SessionServiceProvider session.store als singleton. forgetDrivers() is ook geen API om sessiedata te verwijderen. Een Store opnieuw aanmaken tijdens een lopende request leidt tot inconsistenties met al ingelezen data of andere referenties. De CacheManager in dit voorbeeld houdt ook benoemde stores vast. Wijzig je de verbindingsinstellingen daarvan, dan is alleen de SessionManager opnieuw resolven niet genoeg. Bouw bij deployments met configuratiecache de cache opnieuw op, en herstart ook langlopende workers zodat ze de nieuwe code en configuratie inlezen. Het herstarten van de applicatie en het migreren van opgeslagen data zijn afzonderlijke taken.

Sessieopslag en request-locking staan los van elkaar

Alleen een eigen handler implementeren zorgt er niet voor dat parallelle requests op dezelfde sessie na elkaar worden verwerkt. De blokkering van StartSession gebruikt locks van de cachestore die je met session.block_store kiest, en dat is niet per se dezelfde als de opslag van de sessie zelf. Regel je dit met bijvoorbeeld Route::post(...)->block(), verifieer dan afzonderlijk een cachestore met lockondersteuning, het delen over meerdere servers en de wacht- en vasthoudtijden. Laat de package niet op eigen houtje de blokkering voor de hele applicatie inschakelen.

Test tot en met opslaan en opnieuw inlezen

Laad bij packages die Orchestra Testbench gebruiken de provider en schrijf tests die je eigen driver daadwerkelijk selecteren. Hieronder volgt een voorbeeld van tests/SessionDriverTest.php. De array-cache voor tests gebruikt geen externe verbindingen.
Deze test is een geïsoleerde test die de Store binnen dezelfde applicatie opnieuw aanmaakt. Hij verifieert niet de HTTP-middleware, de heen-en-weerreis van cookies, persistentie naar een ander proces of het verlopen en locken in een echte Redis. Gebruik array niet als gedeelde opslag in productie. Voeg vóór het publiceren van een eigen handler ook het volgende toe.
  • Een niet-opgeslagen of verlopen ID retourneert een lege string
  • De opgeslagen string wordt ongewijzigd hersteld en is na verwijdering niet meer op te halen
  • De eenheid en vernieuwing van de TTL, en het verlopen op de echte backend
  • Mislukt lezen, schrijven of verwijderen levert de vastgelegde retourwaarden of exceptions op
  • De heen-en-weerreis met session.encrypt ingeschakeld en de ondersteunde serialisatieformaten
  • Alleen het laden van de provider benadert de opslag niet en neemt de selectie van ingebouwde drivers niet over
  • Indien nodig HTTP-tests via de echte web-middleware en cookies, en locking van parallelle requests

Gerelateerde pagina’s

Sessies

Sessies lezen en schrijven, flashdata en het opnieuw genereren van het ID.

Interne implementatie van Manager

Het aanmaken en vasthouden van eigen drivers en het delegeren naar de standaarddriver.

Eigen cachestores voor packages

De rolverdeling tussen de cache-Store als opslag en de Repository, en het TTL-contract.

Levensduur van packageservices

Afhankelijkheden die langlopende workers vasthouden en het isoleren van state.

Primaire bronnen

Laatst gewijzigd op 2 november 2026