Session Helper Class
How the Session class wraps PHP's $_SESSION for cleaner code
Wrapping the Session Superglobal
PHP's $_SESSION is a global array that stores user data between requests. DALT.PHP wraps it in a Session class for cleaner, more expressive code.
Think of it like this:
$_SESSIONis the raw storage boxSessionclass is the organized filing system
The Session Class
class Session
{
public static function has(string $key): bool
{
return isset($_SESSION['_flash'][$key]) || isset($_SESSION[$key]);
}
public static function put($key, $value)
{
$_SESSION[$key] = $value;
}
public static function get($key, $default = null)
{
return $_SESSION['_flash'][$key] ?? $_SESSION[$key] ?? $default;
}
public static function flash($key, $value)
{
$_SESSION['_flash'][$key] = $value;
}
public static function unflash()
{
unset($_SESSION['_flash']);
}
public static function flush()
{
$_SESSION = [];
}
public static function destroy()
{
$cookieName = session_name();
static::flush();
if (session_status() === PHP_SESSION_ACTIVE) {
session_destroy();
}
$params = session_get_cookie_params();
setcookie($cookieName, '', time() - 3600,
$params['path'], $params['domain'],
$params['secure'], $params['httponly']);
}
}All methods are static - you call them without creating an instance:
Session::put('user', $userData); // Not: $session->put(...)The Core Methods
put() - Store Data
public static function put($key, $value)
{
$_SESSION[$key] = $value;
}Usage:
Session::put('user', ['email' => 'user@example.com']);
Session::put('cart', ['item1', 'item2']);
Session::put('theme', 'dark');What it does:
- Stores data in
$_SESSION - Data persists across requests
- Available until session ends or is destroyed
Direct equivalent:
$_SESSION['user'] = ['email' => 'user@example.com'];Why use put() instead?
- ✅ More expressive (reads like English)
- ✅ Consistent API across the framework
- ✅ Could add logging/validation later
- ✅ Easier to mock in tests
get() - Retrieve Data
public static function get($key, $default = null)
{
return $_SESSION['_flash'][$key] ?? $_SESSION[$key] ?? $default;
}Usage:
$user = Session::get('user');
$theme = Session::get('theme', 'light'); // Default to 'light'The Priority Chain:
This line is important:
$_SESSION['_flash'][$key] ?? $_SESSION[$key] ?? $defaultIt checks in this order:
- Flash data first (
$_SESSION['_flash'][$key]) - Regular session data (
$_SESSION[$key]) - Default value (
$default)
Why check flash first?
Flash data is temporary and should override regular data for one request:
// Request 1: Form submission fails
Session::flash('errors', ['email' => 'Invalid']);
redirect('/register');
// Request 2: Show form
$errors = Session::get('errors'); // Gets flash data
// Flash takes priority over any regular 'errors' keyThe ?? operator:
- Called "null coalescing operator"
- Returns first non-null value
- Short for:
isset($a) ? $a : $b
has() - Check if Key Exists
public static function has(string $key): bool
{
return isset($_SESSION['_flash'][$key]) || isset($_SESSION[$key]);
}Usage:
if (Session::has('user')) {
echo "User is logged in";
}
if (!Session::has('cart')) {
echo "Cart is empty";
}How it works:
- Uses PHP's native
isset()function to check the_flasharray. - If it's not there, it checks the normal
$_SESSIONarray. - Returns a clean boolean.
Why isset() instead of checking the truthiness of a value?
Imagine a scenario where a session value is mathematically 0, or an empty string "":
Session::put('count', 0);
Session::put('name', '');If the logic used (bool) static::get('count'), it would evaluate to false because 0 is a falsy value in PHP. By using isset(), DALT natively checks if the key actually exists in the array, regardless of whether the value itself is falsy.
flush() - Clear All Session Data
public static function flush()
{
$_SESSION = [];
}Usage:
Session::flush();What it does:
- Empties the entire
$_SESSIONarray - Doesn't destroy the session itself
- Session ID remains the same
- Session cookie still exists
When to use:
- Clearing all data but keeping session active
- Resetting state
Direct equivalent:
$_SESSION = [];destroy() - Complete Session Termination
public static function destroy()
{
$cookieName = session_name();
static::flush();
if (session_status() === PHP_SESSION_ACTIVE) {
session_destroy();
}
$params = session_get_cookie_params();
setcookie($cookieName, '', time() - 3600,
$params['path'], $params['domain'],
$params['secure'], $params['httponly']);
}This is the nuclear option - completely removes the session.
Step-by-step breakdown:
1. Get the session cookie name
$cookieName = session_name();Remember from Part 1.2, DALT sets a custom name:
$sessionName = 'daltphp_' . substr(sha1(BASE_PATH), 0, 8);
session_name($sessionName);So $cookieName might be 'daltphp_a7f3c2e1'.
2. Clear session data
static::flush();Empties $_SESSION.
3. Destroy the session
if (session_status() === PHP_SESSION_ACTIVE) {
session_destroy();
}What session_destroy() does:
- Deletes the session file on the server
- Example:
/tmp/sess_abc123xyzis deleted - Session data is gone forever
Why check session_status()?
- Can't destroy if session isn't active
- Prevents errors
4. Delete the session cookie
$params = session_get_cookie_params();
setcookie($cookieName, '', time() - 3600,
$params['path'], $params['domain'],
$params['secure'], $params['httponly']);What this does:
- Gets current cookie parameters (path, domain, etc.)
- Sets cookie with empty value
- Sets expiry to 1 hour ago (
time() - 3600) - Browser sees expired cookie and deletes it
Why all these steps?
Just calling session_destroy() isn't enough:
- Server-side data is deleted
- But browser still has the cookie
- Next request would create a new session with same ID
- Could cause confusion
By deleting the cookie too:
- Browser forgets the session ID
- Next request gets a fresh session
- Clean slate
Usage in the Framework
During Login
// framework/Core/Authenticator.php
public function login($user)
{
$_SESSION['user'] = [
'email' => $user['email'],
];
session_regenerate_id(true);
}Note
This uses $_SESSION directly, not Session::put().
Why?
- Authenticator is core framework code
- Direct access is fine here
Session::put()is more for application code
Could be rewritten as:
Session::put('user', ['email' => $user['email']]);During Logout
// framework/Core/Authenticator.php
public function logout()
{
Session::destroy();
}This completely removes the session.
In Controllers
// app/Http/controllers/dashboard/index.php
$user = Session::get('user');
if (!$user) {
redirect('/login');
}
view('dashboard/index.view.php', [
'email' => $user['email']
]);Session Lifecycle
Request 1: Login
↓
Session::put('user', [...])
↓
$_SESSION['user'] = [...]
↓
Response sent
↓
PHP writes session to file
↓
Browser receives session cookie
Request 2: Dashboard
↓
Browser sends session cookie
↓
PHP reads session file
↓
$_SESSION populated
↓
Session::get('user')
↓
Returns user data
Request 3: Logout
↓
Session::destroy()
↓
Session file deleted
Cookie deleted
↓
Session goneKey Takeaways
- Session class wraps $_SESSION - Cleaner API
- All methods are static - No instance needed
- get() checks flash first - Flash data has priority
- destroy() is thorough - Clears data, file, and cookie
- has() safely checks key existence - Treats falsy variables fairly using
isset()
What's Good Here
✅ Clean, expressive API
✅ Static methods (convenient)
✅ destroy() is thorough (clears everything)
✅ Consistent with framework style
✅ Accurate key-existence checking in has()
Design Note
DALT keeps sessions intentionally simple and “visible”:
- You can still read and debug
$_SESSIONdirectly at any time. - The helper is just a small wrapper to make common actions easier (get/put/flash/destroy).