Skip to content

Session Management ​

Philosophy ​

Sessions in Nexphant are request-scoped, not global.

Every request gets its own session instance tied to the request lifecycle.

This prevents session leakage across concurrent requests in persistent workers.


Basic Usage ​

Access Session ​

php
use Nexphant\Request;

$app->get('/profile', function (Request $request) {
    $session = $request->session();
    
    $userId = $session->get('user_id');
    
    return ['user_id' => $userId];
});

Global Helper ​

php
$app->get('/cart', function () {
    $items = session()->get('cart', []);
    
    return ['items' => $items];
});

Session API ​

Get Value ​

php
$value = session()->get('key');
$value = session()->get('key', 'default');

Set Value ​

php
session()->put('key', 'value');
session()->put('cart', ['item1', 'item2']);

Check Existence ​

php
if (session()->has('user_id')) {
    // User is logged in
}

Remove ​

php
session()->forget('key');
session()->forget(['key1', 'key2']);

Get and Remove ​

php
$value = session()->pull('key');
$value = session()->pull('key', 'default');

Clear All ​

php
session()->flush();

Flash Data ​

Flash data persists only for the next request.

Set Flash ​

php
session()->flash('message', 'User created successfully');
session()->flash('error', 'Invalid credentials');

Get Flash ​

php
$message = session()->get('message');

Flash data is automatically removed after being read.

Flash Input ​

php
// Flash all input
session()->flashInput($request->all());

// Flash specific fields
session()->flashOnly(['email', 'name']);
session()->flashExcept(['password']);

Old Input ​

php
$email = session()->old('email');
$name = session()->old('name', 'Guest');

Session Security ​

Regenerate ID ​

Regenerate session ID to prevent fixation attacks:

php
session()->regenerate();

Always regenerate after login:

php
$app->post('/login', function (Request $request) {
    $user = authenticate($request->json());
    
    session()->regenerate();
    session()->put('user_id', $user->id);
    
    return ['success' => true];
});

Invalidate Session ​

Destroy session completely:

php
session()->invalidate();

Use on logout:

php
$app->post('/logout', function () {
    session()->invalidate();
    
    return ['success' => true];
});

Storage Drivers ​

Configure in config/session.php:

File Driver ​

php
return [
    'driver' => 'file',
    'path' => storage_path('sessions'),
];

Redis Driver ​

php
return [
    'driver' => 'redis',
    'connection' => 'default',
    'prefix' => 'session:',
];

Database Driver ​

php
return [
    'driver' => 'database',
    'table' => 'sessions',
    'connection' => 'mysql',
];

Array Driver ​

For testing:

php
return [
    'driver' => 'array',
];

Configuration ​

config/session.php:

php
return [
    'driver' => env('SESSION_DRIVER', 'file'),
    
    'lifetime' => 120, // minutes
    
    'expire_on_close' => false,
    
    'encrypt' => false,
    
    'path' => '/',
    
    'domain' => null,
    
    'secure' => env('SESSION_SECURE_COOKIE', false),
    
    'http_only' => true,
    
    'same_site' => 'lax',
    
    'lottery' => [2, 100], // garbage collection
];

Middleware ​

Enable session middleware:

php
use Nexphant\App;
use Nexphant\Server\Middleware\SessionMiddleware;

$app = App::create();

$app->middleware(SessionMiddleware::class);

$app->get('/profile', function (Request $request) {
    // Session available here
    $userId = $request->session()->get('user_id');
    
    return ['user_id' => $userId];
});

Session Lifecycle ​

text
Request
  ↓
Load Session (from storage)
  ↓
Load Flash Data
  ↓
Controller
  ↓
Persist Session (to storage)
  ↓
Response

Complete Example ​

Shopping Cart ​

php
$app->get('/cart', function () {
    $cart = session()->get('cart', []);
    
    return ['items' => $cart];
});

$app->post('/cart', function (Request $request) {
    $cart = session()->get('cart', []);
    $cart[] = $request->json('item');
    
    session()->put('cart', $cart);
    
    return ['success' => true, 'total' => count($cart)];
});

$app->delete('/cart', function () {
    session()->forget('cart');
    
    return ['success' => true];
});

Authentication ​

php
$app->post('/login', function (Request $request) {
    $credentials = $request->json();
    
    $user = User::query()
        ->where('email', $credentials['email'])
        ->first();
    
    if (!$user || !password_verify($credentials['password'], $user->password)) {
        session()->flash('error', 'Invalid credentials');
        return ['success' => false];
    }
    
    session()->regenerate();
    session()->put('user_id', $user->id);
    session()->flash('message', 'Login successful');
    
    return ['success' => true];
});

$app->post('/logout', function () {
    session()->invalidate();
    session()->flash('message', 'Logged out');
    
    return ['success' => true];
});

$app->get('/profile', function () {
    $userId = session()->get('user_id');
    
    if (!$userId) {
        return ['error' => 'Not authenticated'];
    }
    
    $user = User::query()->find($userId);
    
    return ['user' => $user];
});

Form with Flash ​

php
$app->post('/contact', function (Request $request) {
    $data = $request->json();
    
    if (empty($data['email'])) {
        session()->flash('error', 'Email is required');
        session()->flashInput($data);
        
        return ['success' => false];
    }
    
    // Send email...
    
    session()->flash('message', 'Message sent successfully');
    
    return ['success' => true];
});

$app->get('/contact', function () {
    return [
        'message' => session()->get('message'),
        'error' => session()->get('error'),
        'old' => [
            'email' => session()->old('email'),
            'name' => session()->old('name'),
        ],
    ];
});

Fiber Safety ​

Nexphant session storage implementations are fiber-safe.

Each request fiber gets its own session instance.

Session state cannot leak between concurrent requests.


Next Steps ​

Released under the MIT License.