v13.39.0. Pour les opérations de base, consultez Session, et pour le chargement automatique des providers, consultez Découverte automatique des packages.
extend reçoit un handler, pas un Store
Le callback deSession::extend() retourne un handler de stockage qui implémente le SessionHandlerInterface de PHP. Ce n’est pas une API qui retourne directement un Store implémentant Illuminate\Contracts\Session\Session ou un Repository de cache.
SessionManager::callCustomCreator() transmet la valeur de retour du callback à buildSession(), qui l’enveloppe dans un Store ou un EncryptedStore selon session.encrypt. Le nom du cookie et session.serialization sont appliqués à ce moment-là.
Dans le traitement HTTP normal, le middleware StartSession gère le démarrage et l’enregistrement de la session. Pour fournir un handler, le package n’a pas besoin d’appeler session_start() ni session_set_save_handler().
Distinguer les éléments du contrat de stockage
Pour implémenter un backend propre, remplissez les rôles suivants.
Comme le
Store se charge de la sérialisation et de la restauration, le handler ne doit pas appliquer à nouveau serialize() ou json_encode() au tableau de session. Lorsque le chiffrement est activé, stockez tel quel la chaîne traitée par EncryptedStore.
N’enregistrer que la création dans boot
L’exemple minimal suivant réutilise leCacheBasedSessionHandler intégré. Il n’implémente pas de nouveau protocole de stockage : il montre comment enregistrer un driver propre qui utilise un store de cache nommé. Acme\SessionBridge\ correspond à src/ via le PSR-4 de Composer.
Préparez le provider dans src/SessionBridgeServiceProvider.php.
Session::extend() récupère le SessionManager et enregistre la création, mais le store de cache du callback n’est pas encore résolu à ce stade. Le stockage n’est créé que lorsque ce driver est sélectionné pour la première fois. N’exécutez ni vérification de connexion ni écriture de données dans le boot() du provider.
Si vous utilisez votre propre implémentation de SessionHandlerInterface, remplacez le handler retourné par le callback. Aller jusqu’à new Store(...) ne correspond plus à la valeur de retour attendue par le SessionManager.
- Chargez le provider comme un provider normal, non différé.
- Terminez l’enregistrement avant la première utilisation de la session. Si un autre provider résout votre driver plus tôt, vérifiez aussi l’ordre de chargement.
- Utilisez un nom de driver propre au package. Un
extend()portant le même nom écrase la création, et l’enregistrement d’un nom de driver intégré prend le pas sur l’implémentation intégrée.
L’application utilisatrice fait un choix explicite
L’utilisateur modifie les clés correspondantes de sonconfig/session.php existant. Les autres réglages restent en place.
stores existant de config/cache.php. L’exemple suivant utilise la connexion Redis default. La configuration de la connexion Redis et le client nécessaire sont préparés par l’application.
createRedisDriver() du driver de session Redis intégré, ajouter session.connection ou session.prefix ne sera pas automatiquement pris en compte par ce callback.
Ce callback ne modifie ni le Repository ni la configuration du stockage : il utilise le store nommé tel quel. Le store array de test partage lui aussi le même espace de stockage au sein d’une même application.
Le package ne doit pas réécrire inconditionnellement session.driver, le nom du cookie ou le préfixe de cache global de l’application. Vérifiez aussi avec l’utilisateur que l’espace de stockage n’est pas partagé avec d’autres usages et que plusieurs serveurs peuvent utiliser le même stockage.
Préserver l’unité du TTL et le format de stockage
Le constructeur deCacheBasedSessionHandler reçoit la durée de conservation en minutes. Comme write() transmet à chaque fois $minutes * 60 au put() du Repository de cache, l’exemple ci-dessus renouvelle le TTL à chaque écriture. gc() retourne 0 et délègue l’expiration au cache.
En revanche, la durée que StartSession transmet au gc($lifetime) du handler est en secondes. N’implémentez pas un stockage qui utilise directement la valeur de session.lifetime comme des secondes.
Par ailleurs, les changements suivants ne se limitent pas à un renommage de configuration.
Si une mise à jour du package modifie ces éléments, prévoyez des instructions de réauthentification, décidez s’il faut une migration, et envisagez les déploiements où l’ancienne et la nouvelle version coexistent. Comme dans Gestion de la compatibilité de versions de package, incluez le format de stockage et les clés de configuration dans la spécification publique que vous maintenez.
Un Store déjà créé n’est pas remplacé par un simple changement de configuration
Manager, la classe parente du SessionManager, conserve les drivers créés par nom. De plus, SessionServiceProvider enregistre session.store comme singleton.
forgetDrivers() n’est pas non plus une API de suppression des données de session. Recréer le Store pendant une requête en cours provoque des incohérences avec les données déjà lues ou avec d’autres références.
Le CacheManager de cet exemple conserve lui aussi les stores nommés. Si vous modifiez leur configuration de connexion, re-résoudre seulement le SessionManager ne suffit pas.
Dans les déploiements qui utilisent le cache de configuration, reconstruisez le cache, et redémarrez les workers longue durée pour qu’ils chargent le nouveau code et la nouvelle configuration. Le redémarrage de l’application et la migration des données stockées sont deux tâches distinctes.
Le stockage de session et le verrouillage des requêtes sont distincts
Implémenter un handler personnalisé ne suffit pas à sérialiser les requêtes parallèles sur une même session. Le blocage deStartSession utilise les verrous du store de cache choisi avec session.block_store, qui n’est pas forcément le même que le stockage de la session elle-même.
Si vous contrôlez cela avec Route::post(...)->block() ou similaire, vérifiez séparément un store de cache prenant en charge les verrous, le partage entre plusieurs serveurs, ainsi que les durées d’attente et de détention. Le package ne doit pas activer de lui-même le blocage pour toute l’application.
Tester jusqu’à l’enregistrement et la relecture
Pour un package qui utilise Orchestra Testbench, chargez le provider et préparez des tests qui sélectionnent réellement votre driver. Voici un exemple detests/SessionDriverTest.php. Le cache array de test n’utilise aucune connexion externe.
array comme stockage partagé en production.
Avant de publier un handler propre, ajoutez aussi les points suivants.
- Un ID non stocké ou expiré retourne une chaîne vide
- La chaîne stockée est restaurée sans modification et ne peut plus être récupérée après suppression
- L’unité et le renouvellement du TTL, et l’expiration sur le vrai backend
- Les échecs de lecture, d’écriture et de suppression produisent les valeurs de retour ou exceptions définies
- L’aller-retour avec
session.encryptactivé et les formats de sérialisation pris en charge - Le simple chargement du provider n’accède pas au stockage et ne détourne pas la sélection des drivers intégrés
- Si nécessaire, des tests HTTP passant par le vrai middleware
webet les cookies, ainsi que le verrouillage des requêtes parallèles
Pages connexes
Session
Lecture et écriture de session, données flash et régénération de l’ID.
Implémentation interne de Manager
Création et conservation des drivers personnalisés, et délégation au driver par défaut.
Stores de cache personnalisés pour les packages
Répartition des rôles entre le Store de cache servant de stockage et le Repository, et contrat du TTL.
Cycle de vie des services d'un package
Dépendances conservées par les workers longue durée et isolation de l’état.
Sources primaires
- Documentation officielle HTTP Session : drivers personnalisés et blocage
- Documentation officielle du développement de packages
- SessionManager : création personnalisée et construction du Store
- Store : lecture, sérialisation, enregistrement et régénération de l’ID
- CacheBasedSessionHandler : conversion du TTL et contrat de stockage
- CacheManager : stores nommés et configuration Redis
- Manager : extend, driver, forgetDrivers
- SessionServiceProvider : enregistrement singleton du Manager et de session.store
- StartSession : enregistrement, GC et verrouillage par le cache
- CacheBasedSessionHandlerTest officiel : vérification des données absentes, du TTL et de la suppression