Skip to content

Session Management

Phexium abstracts session handling through the Session plugin, enabling different storage backends without changing application code.

Configuration

Configure the session adapter in config/container.php. Two adapters are available:

NativeSession (zero dependencies)

SessionInterface::class => fn (): NativeSession => new NativeSession(
    sessionName: $_ENV['session.native.name'] ?? 'phexium_app',
),

NativeSession uses PHP native functions directly, making it a lightweight alternative when the Odan library features are not required.

OdanSession (feature-rich)

SessionInterface::class => fn (): SessionInterface => match ($_ENV['session.type'] ?? 'odan-memory') {
    'odan-php' => new OdanSession(new PhpSession([
        'name' => $_ENV['session.odan.name'] ?? 'phexium_app',
        'lifetime' => (int) ($_ENV['session.odan.lifetime'] ?? 7200),
        'path' => $_ENV['session.odan.path'] ?? '/',
        'domain' => $_ENV['session.odan.domain'] ?? '',
        'secure' => filter_var($_ENV['session.odan.secure'] ?? false, FILTER_VALIDATE_BOOLEAN),
        'httponly' => filter_var($_ENV['session.odan.httponly'] ?? true, FILTER_VALIDATE_BOOLEAN),
        'samesite' => $_ENV['session.odan.samesite'] ?? 'Lax',
    ])),
    default => new OdanSession(new MemorySession()),
},

Flash Messages

// Add flash message
$this->session->addFlashMessage('success', 'Book created!');

// Display in template
{% for level, messages in flash_messages() %}
    {% for message in messages %}
        <div class="alert alert-{{ level }}">{{ message }}</div>
    {% endfor %}
{% endfor %}

Security Best Practices

Regenerate Session ID on Login

$this->session->regenerateId();
$this->session->set('user_id', $user->id());

Destroy Session on Logout

$this->session->clear();
$this->session->destroy();
session.odan.secure=true      # Only send over HTTPS
session.odan.httponly=true    # Not accessible via JavaScript
session.odan.samesite=Strict  # Prevent CSRF

Testing

For testing, the in-memory session adapter avoids file system dependencies:

SessionInterface::class => new OdanSession(new MemorySession()),

See Also