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 vanSession::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.
Registreer in boot alleen het aanmaken
Het volgende minimale voorbeeld hergebruikt de ingebouwdeCacheBasedSessionHandler. 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 bestaandeconfig/session.php aan. De overige instellingen blijven staan.
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.
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.
Behoud de TTL-eenheid en het opslagformaat
De constructor vanCacheBasedSessionHandler 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 vanStartSession 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 vantests/SessionDriverTest.php. De array-cache voor tests gebruikt geen externe verbindingen.
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.encryptingeschakeld 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
- Officiële HTTP Session-documentatie: eigen drivers en blokkering
- Officiële documentatie over packageontwikkeling
- SessionManager: eigen aanmaak en opbouw van de Store
- Store: inlezen, serialisatie, opslaan en opnieuw genereren van het ID
- CacheBasedSessionHandler: TTL-conversie en opslagcontract
- CacheManager: benoemde stores en Redis-configuratie
- Manager: extend, driver en forgetDrivers
- SessionServiceProvider: singletonregistratie van de Manager en session.store
- StartSession: opslaan, GC en locking via de cache
- Officiële CacheBasedSessionHandlerTest: verificatie van ontbrekende data, TTL en verwijdering