Zum Hauptinhalt springen
Wenn ein Paket einen eigenen Session-Speicher bereitstellen soll, trennen Sie die Registrierung der Speicherlogik von der Auswahl durch die Anwendung. Die bloße Installation sollte den Speicherort des Login-Zustands nicht umstellen. Gestalten Sie das Paket so, dass Nutzer die Auswirkungen auf bestehende Sessions prüfen können, bevor sie es aktivieren. Diese Seite basiert auf dem offiziellen Quellcode von Laravel Framework 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 von Session::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.
Unterscheiden Sie fehlende Daten von Backend-Fehlern. Im geprüften Code behandelt Store::readFromHandler() ein leeres Leseergebnis oder false als leere Session. Außerdem prüft Store::save() den Rückgabewert von write() des Handlers nicht.Soll Ihr Paket Fehler stets als Exceptions behandeln, legen Sie die Strategie ausdrücklich fest und testen Sie sie: Unterdrücken Sie keine Exceptions des Speichers, und erkennen Sie bei Backends, die false zurückgeben, dies im Handler und wandeln Sie es in eine Exception um. Laravel wiederholt fehlgeschlagene Speichervorgänge nicht zwingend automatisch und meldet sie auch nicht zwingend.

In boot nur die Erzeugungslogik registrieren

Das folgende Minimalbeispiel verwendet den eingebauten CacheBasedSessionHandler 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 bestehenden config/session.php und lassen die übrigen Einstellungen unverändert.
Für den Speicher ergänzen Sie einen benannten Store im bestehenden Array 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.
Verbindung und Präfix ergeben sich in diesem Beispiel aus der Konfiguration des Cache-Stores. Da 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.
Wenn Sie nur gewöhnliche Speicherung in Redis oder einer Datenbank benötigen, verwenden Sie zunächst die eingebauten Session-Treiber. Ein eigener Treiber ist ein Erweiterungspunkt für Fälle, in denen Sie einen neuen Speicher oder zusätzliche Speicherkonventionen brauchen.

TTL-Einheit und Speicherformat beibehalten

Der Konstruktor von CacheBasedSessionHandler 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 von StartSession 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 zeigt tests/SessionDriverTest.php. Der array-Cache für Tests nutzt keine externe Verbindung.
Dieser Test ist ein isolierter Test, der den Store innerhalb derselben Anwendung neu erzeugt. Er prüft weder HTTP-Middleware noch den Cookie-Hin- und Rückweg, die Persistenz über Prozessgrenzen hinweg oder den tatsächlichen Ablauf und das Locking in Redis. Verwenden Sie 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.encrypt sowie 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

Zuletzt geändert am 2. November 2026