v13.39.0. Die Grundlagen finden Sie unter Session, das automatische Laden von Providern unter Paket-Discovery.
extend erhält einen Handler, keinen Store
Der Callback vonSession::extend() gibt einen Speicher-Handler zurück, der PHPs SessionHandlerInterface implementiert. Es handelt sich nicht um eine API, die einen Store mit Illuminate\Contracts\Session\Session oder direkt ein Cache-Repository zurückgibt.
SessionManager::callCustomCreator() übergibt den Rückgabewert des Callbacks an buildSession(), das ihn je nach session.encrypt mit einem Store oder einem EncryptedStore umhüllt. Dabei werden auch der Cookie-Name und session.serialization angewendet.
In der normalen HTTP-Verarbeitung verwaltet die Middleware StartSession den Start und das Speichern der Session. Um einen Handler bereitzustellen, muss Ihr Paket weder session_start() noch session_set_save_handler() aufrufen.
Den Speichervertrag in Teilen betrachten
Wenn Sie ein eigenes Backend implementieren, erfüllen Sie die folgenden Aufgaben.
Da der
Store für Serialisierung und Wiederherstellung zuständig ist, darf der Handler das Session-Array nicht erneut mit serialize() oder json_encode() verarbeiten. Auch bei aktivierter Verschlüsselung speichern Sie den von EncryptedStore verarbeiteten String unverändert.
In boot nur die Erzeugungslogik registrieren
Das folgende Minimalbeispiel verwendet den eingebautenCacheBasedSessionHandler wieder. Es implementiert kein neues Speicherprotokoll, sondern zeigt, wie Sie einen eigenen Treiber registrieren, der einen benannten Cache-Store nutzt. Acme\SessionBridge\ ist per Composer-PSR-4 auf src/ abgebildet.
Legen Sie den Provider in src/SessionBridgeServiceProvider.php an.
Session::extend() holt den SessionManager und registriert die Erzeugungslogik, der Cache-Store im Callback wird zu diesem Zeitpunkt aber noch nicht aufgelöst. Der Speicher wird erst erzeugt, wenn der Treiber zum ersten Mal ausgewählt wird. Führen Sie im boot() des Providers keine Verbindungsprüfungen und keine Speichervorgänge aus.
Wenn Sie eine eigene Implementierung von SessionHandlerInterface verwenden, tauschen Sie den Handler aus, den der Callback zurückgibt. Gehen Sie bis zu new Store(...), passt der Rückgabewert nicht mehr zu dem, was der SessionManager erwartet.
- Laden Sie den Provider als normalen, nicht verzögerten Provider.
- Schließen Sie die Registrierung ab, bevor die Session zum ersten Mal verwendet wird. Wenn ein anderer Provider Ihren Treiber früher auflöst, prüfen Sie auch die Ladereihenfolge.
- Verwenden Sie einen paketspezifischen Treibernamen. Ein
extend()mit demselben Namen überschreibt die Erzeugungslogik, und die Registrierung eines eingebauten Treibernamens hat Vorrang vor der eingebauten Implementierung.
Die nutzende Anwendung wählt explizit aus
Nutzer ändern die betreffenden Schlüssel in ihrer bestehendenconfig/session.php und lassen die übrigen Einstellungen unverändert.
stores von config/cache.php. Das folgende Beispiel nutzt die Redis-Verbindung default. Die Redis-Verbindungseinstellungen und den benötigten Client stellt die Anwendung bereit.
createRedisDriver() des eingebauten Redis-Session-Treibers nicht durchlaufen wird, übernimmt dieser Callback session.connection oder session.prefix nicht automatisch, auch wenn Sie sie ergänzen.
Dieser Callback verändert weder das Repository noch die Speicherkonfiguration, sondern nutzt den benannten Store unverändert. Auch ein array-Store für Tests teilt innerhalb derselben Anwendung denselben Speicherbereich.
Überschreiben Sie session.driver, den Cookie-Namen oder das anwendungsweite Cache-Präfix nicht bedingungslos aus Ihrem Paket heraus. Klären Sie mit den Nutzern auch, dass der Speicherbereich nicht mit anderen Zwecken geteilt wird und dass mehrere Server denselben Speicher nutzen können.
TTL-Einheit und Speicherformat beibehalten
Der Konstruktor vonCacheBasedSessionHandler erhält die Lebensdauer in Minuten. write() übergibt bei jedem Aufruf $minutes * 60 an put() des Cache-Repositorys, sodass die TTL im obigen Beispiel bei jedem Schreibvorgang erneuert wird. gc() gibt 0 zurück und überlässt den Ablauf dem Cache.
Die Lebensdauer, die StartSession an gc($lifetime) des Handlers übergibt, ist dagegen in Sekunden angegeben. Implementieren Sie nichts, das den Wert von session.lifetime unverändert als Sekunden speichert.
Die folgenden Änderungen sind außerdem mit mehr als einer Umbenennung der Einstellung verbunden.
Wenn ein Paket-Update eines dieser Elemente ändert, berücksichtigen Sie Hinweise zur erneuten Anmeldung, eine mögliche Migration und Deployments, in denen alte und neue Versionen parallel laufen. Wie bei der Versionskompatibilität von Paketen zählen auch Speicherformat und Konfigurationsschlüssel zur öffentlichen Spezifikation, die Sie pflegen.
Eine Konfigurationsänderung allein ersetzt einen erzeugten Store nicht
Manager, die Elternklasse von SessionManager, hält erzeugte Treiber nach Namen vor. Zusätzlich registriert SessionServiceProvider session.store als Singleton.
forgetDrivers() ist auch keine API zum Löschen von Session-Daten. Wird der Store während einer laufenden Anfrage neu erzeugt, entstehen Inkonsistenzen mit bereits geladenen Daten und anderen Referenzen.
Auch der CacheManager in diesem Beispiel hält benannte Stores vor. Ändern Sie deren Verbindungskonfiguration, reicht es nicht, nur den SessionManager neu aufzulösen.
Bei Deployments mit Konfigurations-Cache bauen Sie den Cache neu auf und starten langlebige Worker neu, damit sie den neuen Code und die neue Konfiguration laden. Der Neustart der Anwendung und die Migration gespeicherter Daten sind getrennte Aufgaben.
Session-Speicherung und Request-Locking sind getrennt
Allein durch die Implementierung eines eigenen Handlers werden parallele Anfragen an dieselbe Session nicht serialisiert. Das Blocking vonStartSession nutzt Locks des Cache-Stores, der über session.block_store gewählt wird. Dieser ist nicht zwingend derselbe wie der Speicher der Session selbst.
Wenn Sie dies etwa mit Route::post(...)->block() steuern, prüfen Sie separat einen Lock-fähigen Cache-Store, die gemeinsame Nutzung über mehrere Server sowie Warte- und Haltezeiten. Ihr Paket sollte anwendungsweite Blocking-Einstellungen nicht eigenmächtig aktivieren.
Bis zum Speichern und erneuten Laden testen
In Paketen mit Orchestra Testbench laden Sie den Provider und schreiben Tests, die Ihren eigenen Treiber tatsächlich auswählen. Das folgende Beispiel zeigttests/SessionDriverTest.php. Der array-Cache für Tests nutzt keine externe Verbindung.
array nicht als gemeinsamen Speicher in Produktion.
Bevor Sie einen eigenen Handler veröffentlichen, ergänzen Sie außerdem Folgendes.
- Nicht gespeicherte oder abgelaufene IDs liefern einen leeren String
- Ein gespeicherter String wird unverändert wiederhergestellt und ist nach dem Löschen nicht mehr abrufbar
- TTL-Einheit und Erneuerung sowie der Ablauf im echten Backend
- Fehler beim Lesen, Schreiben und Löschen führen zu den festgelegten Rückgabewerten oder Exceptions
- Hin- und Rückweg mit aktiviertem
session.encryptsowie die unterstützten Serialisierungsformate - Das bloße Laden des Providers greift nicht auf den Speicher zu und übernimmt nicht die Auswahl eingebauter Treiber
- Bei Bedarf HTTP-Tests über die echte
web-Middleware und Cookies sowie Locking bei parallelen Anfragen
Verwandte Seiten
Session
Lesen und Schreiben von Sessions, Flash-Daten und das Neugenerieren von IDs.
Interne Implementierung von Manager
Erzeugung und Vorhalten eigener Treiber sowie die Delegation an den Standardtreiber.
Eigene Cache-Stores in Paketen
Aufgabenteilung zwischen Cache-Store und Repository als Speicher sowie der TTL-Vertrag.
Lebenszyklus von Paketdiensten
Von langlebigen Workern vorgehaltene Abhängigkeiten und die Isolation von Zustand.
Herangezogene Primärquellen
- Offizielle HTTP-Session-Dokumentation: eigene Treiber und Blocking
- Offizielle Dokumentation zur Paketentwicklung
- SessionManager: eigene Erzeugung und Aufbau des Stores
- Store: Laden, Serialisierung, Speichern und Neugenerieren von IDs
- CacheBasedSessionHandler: TTL-Umrechnung und Speichervertrag
- CacheManager: benannte Stores und Redis-Konfiguration
- Manager: extend, driver, forgetDrivers
- SessionServiceProvider: Singleton-Registrierung von Manager und session.store
- StartSession: Speichern, GC und Locking über den Cache
- Offizieller CacheBasedSessionHandlerTest: Prüfung fehlender Daten, TTL und Löschen