nicolas2-dev/npds-session

Lightweight PHP Session Manager inspired by Laravel and Symfony

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/nicolas2-dev/npds-session

2.0.0 2025-12-19 17:41 UTC

This package is auto-updated.

Last update: 2025-12-19 17:42:31 UTC


README

Une bibliothèque PHP légère et sans dépendances pour la gestion des sessions, inspirée par Laravel et Symfony.

Installation

composer require npds/session

Table des matières

Introduction

Cette bibliothèque fournit une interface orientée objet pour gérer les sessions PHP. Elle supporte le stockage des données de session, les messages flash, la régénération des sessions, et offre une gestion centralisée sans aucune dépendance externe. Choisissez entre les sessions natives PHP, le stockage fichier, ou les tableaux en mémoire pour les tests.

Classes principales

Npds\Session\SessionManager

Classe principale de gestion des sessions qui gère l'initialisation, la manipulation des données et le cycle de vie de la session.

Npds\Session\Session

Façade statique pour un accès simple à la session avec initialisation automatique et gestion de l'arrêt.

Npds\Session\SessionInterface

Interface définissant tous les opérations et contrats de session.

Session Manager

Initialisation

use Npds\Session\SessionManager;

// Créer avec la configuration par défaut
$sessionManager = new SessionManager();

// Créer avec une configuration personnalisée
$sessionManager = new SessionManager([
    'name' => 'MA_SESSION',
    'lifetime' => 7200,           // 2 heures
    'path' => '/',
    'domain' => 'example.com',
    'secure' => true,             // HTTPS uniquement
    'httponly' => true,           // Inaccessible en JavaScript
    'samesite' => 'Lax',          // Protection CSRF : Strict, Lax, None
    'driver' => 'native',         // native, array, ou file
    'encrypt' => false,           // Chiffrer les données
    'files' => '/var/sessions',   // Répertoire des fichiers (pour file driver)
    'lottery' => [2, 100]         // Probabilité du garbage collection
]);

// Démarrer la session
$sessionManager->start();

// Vérifier si la session est active
if ($sessionManager->isStarted()) {
    echo 'La session est active';
}

Drivers disponibles

  • native : Utilise le superglobal $_SESSION natif de PHP
  • array : Stockage en mémoire (parfait pour les tests)
  • file : Stockage basé sur des fichiers avec répertoire personnalisé

Opérations de base

$session = $sessionManager;

// Ajouter une valeur
$session->put('user_id', 123);
$session->put('user_data', [
    'name' => 'Jean Dupont',
    'email' => 'jean@example.com'
]);

// Récupérer une valeur
$userId = $session->get('user_id');           // 123
$userName = $session->get('user_data.name');  // 'Jean Dupont'
$missing = $session->get('missing', 'défaut'); // 'défaut'

// Vérifier si une clé existe
if ($session->has('user_id')) {
    echo 'L\'ID utilisateur est défini';
}

// Récupérer et supprimer
$value = $session->pull('temporary_key', 'défaut');

// Récupérer toutes les données
$allData = $session->all();

// Supprimer une clé
$session->forget('temporary_key');

// Vider toutes les données
$session->flush();

Travailler avec des tableaux

$session->put('preferences', [
    'theme' => 'dark',
    'language' => 'fr',
    'notifications' => true
]);

// Récupérer une valeur imbriquée
$theme = $session->get('preferences.theme'); // 'dark'

// Mettre à jour une valeur imbriquée
$session->put('preferences.theme', 'light');

Opérations numériques

// Incrémenter
$session->put('page_views', 0);
$views = $session->increment('page_views');     // 1
$views = $session->increment('page_views', 5);  // 6

// Décrémenter
$views = $session->decrement('page_views');     // 5
$views = $session->decrement('page_views', 2);  // 3

Messages Flash

Les messages flash persistent uniquement pour la prochaine requête, puis sont automatiquement supprimés.

// Ajouter un message flash
$session->flash('status', 'Profil mis à jour avec succès');
$session->flash('errors', ['email' => 'Email invalide']);

// Les données flash sont disponibles dans la requête actuelle et la prochaine
$session->save();
$session->start(); // Requête suivante

$status = $session->get('status'); // 'Profil mis à jour avec succès'

// Sauvegarder à nouveau - les données flash sont maintenant supprimées
$session->save();
$session->start(); // Requête d'après

$status = $session->get('status'); // null

Flash Now (Flash immédiat)

Les données flash disponibles uniquement dans la requête actuelle.

$session->now('message', 'Message immédiat');

$message = $session->get('message'); // 'Message immédiat'

// Après sauvegarde et démarrage d'une nouvelle session
$session->save();
$session->start();

$message = $session->get('message'); // null

Conserver les données flash

Préserver certaines données flash pour la prochaine requête.

// Première requête
$session->flash('message', 'Succès!');
$session->flash('error', 'Quelque chose a échoué');
$session->save();

// Deuxième requête
$session->start();
$session->keep('message'); // Garder seulement ce message flash
$session->save();

// Troisième requête
$session->start();
$session->get('message'); // 'Succès!' (toujours disponible)
$session->get('error');   // null (n'a pas été gardé)

Reflash des données

Préserver toutes les données flash actuelles pour la prochaine requête.

$session->flash('message1', 'Premier message');
$session->flash('message2', 'Deuxième message');

// Garder toutes les données flash pour la prochaine requête
$session->reflash();

$session->save();
$session->start();

$session->get('message1'); // 'Premier message'
$session->get('message2'); // 'Deuxième message'

Régénération de la session

Régénérer l'ID de session pour la sécurité, surtout après connexion/déconnexion.

// Régénérer l'ID de session (garde les données)
$oldId = $session->getId();
$session->regenerate();
$newId = $session->getId();
// $oldId !== $newId, mais les données persistent

// Régénérer et détruire l'ancienne session (supprime les données)
$session->regenerate(true);
$session->get('user_data'); // null

Gestion de l'ID de session

// Récupérer l'ID de session actuel
$sessionId = $session->getId();

// Définir un ID de session personnalisé (avant démarrage)
$newSession = new SessionManager(['driver' => 'array']);
$newSession->setId('custom_id_12345');
$newSession->start();

// Récupérer le nom de la session
$sessionName = $session->getName(); // 'npds_session' ou personnalisé

// Définir le nom de la session (avant démarrage)
$session->setName('MA_SESSION_PERSONNALISEE');

Support des Namespaces

Organiser les données de session dans des namespaces pour éviter les conflits.

// Section admin
$session->setNamespace('admin');
$session->put('user', 'admin1');
$session->put('permissions', ['edit', 'delete']);

// Section utilisateur
$session->setNamespace('user');
$session->put('user', 'user1');
$session->get('user'); // 'user1'

// Revenir au namespace admin
$session->setNamespace('admin');
$session->get('user'); // 'admin1'

// Namespace par défaut
$session->setNamespace('');
$session->put('global', 'data');

Sauvegarde et nettoyage

// Sauvegarder la session
$session->save();

// Détruire la session entière
$session->destroy();

// Vérifier si la session est toujours active
if (!$session->isStarted()) {
    echo 'La session a été détruite';
}

// Garbage collection (automatique avec file driver)
$session->gc(3600); // Supprimer les fichiers plus vieux que 3600 secondes

Gestion de la configuration

// Récupérer la configuration complète
$config = $session->getConfig();

// Récupérer une valeur de configuration spécifique
$driver = $session->getConfig()['driver'];

// Définir la configuration
$session->setConfig('lifetime', 3600);
$session->setConfig('secure', true);

Façade Session

Interface statique simple pour accéder à la session avec initialisation automatique.

Accès statique

use Npds\Session\Session;

// Initialiser avec configuration (une seule fois nécessaire)
Session::init([
    'driver' => 'native',
    'lifetime' => 7200,
    'secure' => true
]);

// Utiliser les méthodes statiques
Session::put('user_id', 123);
Session::get('user_id'); // 123
Session::has('user_id'); // true

// Récupérer l'instance du manager
$manager = Session::getInstance();

Toutes les méthodes statiques disponibles

use Npds\Session\Session;

// Opérations de données
Session::put('key', 'value');
Session::get('key', 'défaut');
Session::has('key');
Session::forget('key');
Session::pull('key', 'défaut');
Session::flush();

// Opérations numériques
Session::increment('counter');
Session::decrement('counter');

// Opérations flash
Session::flash('message', 'Succès');
Session::now('immediate', 'Seulement maintenant');
Session::reflash();
Session::keep('message');

// Opérations de session
Session::id();              // Récupérer l'ID
Session::regenerate();      // Régénérer l'ID
Session::all();             // Récupérer toutes les données

// Gestion
Session::resetInstance();   // Réinitialiser pour les tests

Gestion automatique de l'arrêt

La façade sauvegarde automatiquement la session à l'arrêt du script :

use Npds\Session\Session;

Session::init();
Session::put('user_id', 123);

// La session est automatiquement sauvegardée à la fin du script
// Pas besoin d'appeler save() manuellement

Exemples complets

Exemple 1 : Authentification utilisateur

use Npds\Session\SessionManager;

class ManagerAuth
{
    private SessionManager $session;
    
    public function __construct(SessionManager $session)
    {
        $this->session = $session;
    }
    
    public function login(int $userId, string $username, bool $remember = false): void
    {
        // Régénérer la session après la connexion
        $this->session->regenerate();
        
        // Stocker les données utilisateur
        $this->session->put('auth.user_id', $userId);
        $this->session->put('auth.username', $username);
        $this->session->put('auth.logged_in_at', time());
        
        if ($remember) {
            $this->session->put('auth.remember', true);
            // Prolonger la durée de vie à 30 jours
            $this->session->setConfig('lifetime', 30 * 24 * 3600);
        }
        
        $this->session->flash('status', 'Bienvenue!');
        $this->session->save();
    }
    
    public function logout(): void
    {
        $this->session->flash('status', 'Vous avez été déconnecté');
        $this->session->save();
        $this->session->destroy();
    }
    
    public function isAuthenticated(): bool
    {
        return $this->session->has('auth.user_id');
    }
    
    public function getUser(): ?array
    {
        if (!$this->isAuthenticated()) {
            return null;
        }
        
        return [
            'id' => $this->session->get('auth.user_id'),
            'username' => $this->session->get('auth.username'),
            'logged_in_at' => $this->session->get('auth.logged_in_at')
        ];
    }
}

// Utilisation
$session = new SessionManager(['driver' => 'native', 'secure' => true]);
$session->start();

$auth = new ManagerAuth($session);

// Connexion
$auth->login(1, 'jean_dupont', true);

// Vérifier le statut
if ($auth->isAuthenticated()) {
    $user = $auth->getUser();
    echo "Bienvenue {$user['username']}!";
}

// Déconnexion
$auth->logout();

Exemple 2 : Panier d'achat

use Npds\Session\SessionManager;

class Panier
{
    private SessionManager $session;
    
    public function __construct(SessionManager $session)
    {
        $this->session = $session;
        $this->session->setNamespace('panier');
    }
    
    public function addItem(int $productId, int $quantity = 1): void
    {
        $items = $this->session->get('items', []);
        
        if (isset($items[$productId])) {
            $items[$productId]['quantity'] += $quantity;
        } else {
            $items[$productId] = ['quantity' => $quantity];
        }
        
        $this->session->put('items', $items);
        $this->session->flash('message', "Produit #{$productId} ajouté au panier");
    }
    
    public function removeItem(int $productId): void
    {
        $items = $this->session->get('items', []);
        unset($items[$productId]);
        $this->session->put('items', $items);
    }
    
    public function getItems(): array
    {
        return $this->session->get('items', []);
    }
    
    public function getCount(): int
    {
        $items = $this->getItems();
        return array_sum(array_column($items, 'quantity'));
    }
    
    public function clear(): void
    {
        $this->session->forget('items');
        $this->session->flash('message', 'Panier vidé');
    }
}

// Utilisation
$session = new SessionManager(['driver' => 'native']);
$session->start();

$panier = new Panier($session);

$panier->addItem(1, 2);    // Ajouter produit 1 (quantité 2)
$panier->addItem(2, 1);    // Ajouter produit 2 (quantité 1)

echo "Articles dans le panier: " . $panier->getCount(); // 3

$items = $panier->getItems();
print_r($items);

$session->save();

Exemple 3 : Gestion des erreurs de formulaire

use Npds\Session\SessionManager;

class ManagerFormulaire
{
    private SessionManager $session;
    
    public function __construct(SessionManager $session)
    {
        $this->session = $session;
    }
    
    public function validateAndSave(array $data): bool
    {
        $errors = [];
        
        // Valider l'email
        if (empty($data['email']) || !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
            $errors['email'] = 'Adresse email invalide';
        }
        
        // Valider le nom
        if (empty($data['name']) || strlen($data['name']) < 3) {
            $errors['name'] = 'Le nom doit contenir au moins 3 caractères';
        }
        
        if (!empty($errors)) {
            // Flash les erreurs pour affichage à la prochaine requête
            $this->session->flash('errors', $errors);
            $this->session->flash('old_data', $data);
            $this->session->save();
            return false;
        }
        
        // Sauvegarder les données
        $this->session->put('user_data', $data);
        $this->session->flash('success', 'Données sauvegardées avec succès');
        $this->session->save();
        return true;
    }
    
    public function getErrors(): ?array
    {
        return $this->session->get('errors');
    }
    
    public function getOldData(): ?array
    {
        return $this->session->get('old_data');
    }
}

// Utilisation
$session = new SessionManager(['driver' => 'native']);
$session->start();

$form = new ManagerFormulaire($session);

// Valider et traiter le formulaire
$form->validateAndSave($_POST);

// Dans le template, afficher les erreurs si présentes
if ($form->getErrors()) {
    foreach ($form->getErrors() as $field => $error) {
        echo "<span class='error'>$error</span>";
    }
}

$session->save();

Exemple 4 : Utiliser la Façade Session

use Npds\Session\Session;

// Initialiser une seule fois
Session::init([
    'driver' => 'native',
    'lifetime' => 7200,
    'secure' => true,
    'httponly' => true
]);

// Utiliser partout sans initialisation
class ControllerUtilisateur
{
    public function store()
    {
        Session::put('user_id', 123);
        Session::put('user_email', 'user@example.com');
        
        Session::flash('success', 'Utilisateur créé avec succès');
        
        // Flash automatiquement sauvegardé à la fin du script
    }
    
    public function show()
    {
        if (Session::has('user_id')) {
            echo Session::get('user_email');
        }
    }
}

// Une autre classe
class ControllerPanier
{
    public function add()
    {
        Session::setNamespace('panier');
        Session::put('items', [1, 2, 3]);
        
        Session::flash('message', 'Article ajouté au panier');
        // Gestion automatique de l'arrêt - pas besoin de save() manuel
    }
}

Bonnes pratiques

1. Configuration sécurisée de la session

$secure_config = [
    'driver' => 'file',
    'lifetime' => 3600,           // 1 heure
    'path' => '/',
    'secure' => true,             // HTTPS uniquement
    'httponly' => true,           // Pas d'accès JavaScript
    'samesite' => 'Strict',       // Protection CSRF
    'files' => '/var/sessions',   // En dehors de la racine web
    'encrypt' => true             // Chiffrer les données sensibles
];

$session = new SessionManager($secure_config);
$session->start();

2. Régénérer lors des changements d'authentification

public function login()
{
    // Valider les identifiants...
    
    // Régénérer l'ID de session pour prévenir la fixation
    $session->regenerate();
    
    $session->put('user_id', $userId);
    $session->save();
}

public function logout()
{
    // Détruire complètement à la déconnexion
    $session->destroy();
}

3. Utiliser les Namespaces pour l'organisation

// Séparer les préoccupations avec les namespaces
$session->setNamespace('auth');
$session->put('user_id', 123);

$session->setNamespace('panier');
$session->put('items', []);

$session->setNamespace('preferences');
$session->put('theme', 'dark');

4. Valider l'existence des données flash

// Toujours vérifier l'existence des données flash avant utilisation
if ($session->has('errors')) {
    $errors = $session->get('errors');
    // Afficher les erreurs...
}

// Ou utiliser get avec valeur par défaut
$errors = $session->get('errors', []);

5. Nettoyer les anciennes sessions

// Pour file driver, lancer le garbage collection
if (rand(1, 100) <= 2) {  // 2% de chance
    $session->gc(7200); // Supprimer les fichiers plus vieux que 2 heures
}

6. Tester avec Array Driver

// Tests unitaires - pas besoin d'I/O fichier
$session = new SessionManager(['driver' => 'array']);
$session->start();

$session->put('test', 'value');
assert($session->get('test') === 'value');

Session::resetInstance(); // Réinitialiser pour le test suivant

Référence complète de l'API

Méthodes du SessionManager

Cycle de vie de la session

  • start(): bool - Démarrer la session
  • save(): bool - Sauvegarder la session
  • destroy(): bool - Détruire la session entière
  • isStarted(): bool - Vérifier si la session est active
  • gc(?int $lifetime): int - Garbage collection pour les sessions fichier

Opérations de données

  • put(string $key, mixed $value): void - Stocker une valeur
  • get(string $key, mixed $default): mixed - Récupérer une valeur
  • has(string $key): bool - Vérifier si une clé existe
  • forget(string $key): void - Supprimer une clé
  • pull(string $key, mixed $default): mixed - Récupérer et supprimer
  • all(): array - Récupérer toutes les données
  • flush(): void - Vider toutes les données

Opérations numériques

  • increment(string $key, int $amount = 1): int - Incrémenter une valeur
  • decrement(string $key, int $amount = 1): int - Décrémenter une valeur

Données flash

  • flash(string $key, mixed $value): void - Ajouter un flash (persiste une requête)
  • now(string $key, mixed $value): void - Flash pour requête actuelle uniquement
  • reflash(): void - Garder toutes les données flash pour la prochaine requête
  • keep(array|string $keys): void - Garder certaines données flash

Gestion de la session

  • getId(): string - Récupérer l'ID de session
  • setId(string $id): void - Définir l'ID (avant démarrage)
  • regenerate(bool $destroy = false): bool - Régénérer l'ID
  • setNamespace(string $namespace): void - Définir le namespace des données
  • getNamespace(): string - Récupérer le namespace actuel

Configuration

  • getConfig(): array - Récupérer la configuration complète
  • setConfig(string $key, mixed $value): void - Définir une valeur config
  • getStore(): SessionInterface - Récupérer le stockage sous-jacent

Méthodes statiques de la Façade Session

Toutes les méthodes du SessionManager disponibles en statique, plus :

  • init(array $config): SessionManager - Initialiser avec configuration
  • getInstance(): SessionManager - Récupérer l'instance du manager
  • resetInstance(): void - Réinitialiser l'instance (tests)

Conclusion

La bibliothèque npds-session fournit une solution légère et indépendante du framework pour la gestion des sessions. Avec le support de plusieurs drivers, des messages flash, des namespaces, et une conception orientée sécurité, elle est parfaite pour les petits projets comme pour les grandes applications.

Fonctionnalités principales :

  • Zéro dépendances
  • Plusieurs drivers de stockage (native, file, array)
  • Système de messages flash sécurisé
  • Régénération de session pour l'authentification
  • Support des namespaces pour l'organisation des données
  • Façade statique pour un accès pratique
  • Gestion automatique de l'arrêt
  • Couverture complète de tests

Pour plus d'informations, visitez le dépôt GitHub.