DALT.PHP
Framework Deep Dive1. Entry Point

Session Management

How sessions work and why they must start before any output

The Memory Box for Users

HTTP is "stateless" - each request is independent. Without sessions, the server forgets you between requests.

A session is how the server remembers small data about you:

  • "This user is logged in"
  • "This user has items in their cart"
  • "This form had validation errors"

How Sessions Work

  1. First visit: Server creates a unique session ID (random string)
  2. Cookie sent: Server sends this ID to your browser as a cookie
  3. Browser stores: Your browser saves the cookie
  4. Next request: Browser sends the cookie back with every request
  5. Server remembers: Server uses the ID to load your session data

Think of it like a coat check:

  • You give your coat (data) to the attendant (server)
  • They give you a ticket (session ID cookie)
  • You show the ticket on your next visit
  • They return your coat (session data)

Session Name: Avoiding Collisions

$sessionName = 'daltphp_' . substr(sha1(BASE_PATH), 0, 8);
session_name($sessionName);

session_set_cookie_params([
    'lifetime' => 0,
    'path'     => '/',
    'secure'   => !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off',
    'httponly' => true,
    'samesite' => 'Lax',
]);

session_start();

Why a Custom Session Name?

By default, PHP uses PHPSESSID as the session cookie name. But what if you run two PHP apps on localhost?

The Problem:

App 1: localhost:8000 → uses PHPSESSID
App 2: localhost:8001 → uses PHPSESSID

Both apps share the same cookie name on the same domain. They can:

  • Overwrite each other's sessions
  • Cause confusing login/logout behavior
  • Mix up user data

The Solution:

$sessionName = 'daltphp_' . substr(sha1(BASE_PATH), 0, 8);
// Result: 'daltphp_a7f3c2e1'

This creates a unique session name based on your project path:

  • Different projects get different session names
  • No more collisions on localhost
  • Each app has its own "coat check counter"

Breaking Down the Code

sha1(BASE_PATH)

  • Creates a hash of your project path
  • Example: /home/user/project1a7f3c2e1b9d4...

substr(..., 0, 8)

  • Takes first 8 characters of the hash
  • Keeps the name short but unique enough

'daltphp_' . ...

  • Adds a readable prefix
  • Final result: daltphp_a7f3c2e1

Starting the Session

session_name($sessionName);
session_start();

The Critical Order

You must call session_name() before session_start(). Here's why:

What session_name() does:

  • Sets the name of the session cookie
  • Must be called before any session operations

What session_start() does:

  • Reads the session cookie from the browser
  • Loads session data from the server
  • Fills the $_SESSION array
  • Sends session cookie headers if needed

The Headers Problem

Sessions use HTTP cookies, which are sent in headers. In HTTP:

HTTP/1.1 200 OK
Set-Cookie: daltphp_a7f3c2e1=abc123xyz...  ← Headers
Content-Type: text/html                     ← Headers
                                            ← Blank line
<html>                                      ← Body starts here

The Rule: Headers must be sent before the body.

If you output anything before session_start():

echo "Hello";           // ← Output sent (body starts)
session_start();        // ← ERROR! Can't send headers now

You'll get:

Warning: session_start(): Cannot send session cookie - 
headers already sent by (output started at ...)

Why This File is Safe

In public/index.php:

  • No echo, print, or HTML before session_start()
  • No whitespace before <?php
  • No included files that output content

This is intentional and important.


What Gets Stored in Sessions

After session_start(), you can use $_SESSION:

// Store data
$_SESSION['user'] = ['email' => 'user@example.com'];
$_SESSION['cart'] = ['item1', 'item2'];

// Read data
if (isset($_SESSION['user'])) {
    echo "Welcome back!";
}

// Delete data
unset($_SESSION['cart']);

Session Data Lives on the Server

Important: The cookie only stores the session ID, not the actual data.

In the browser cookie:

daltphp_a7f3c2e1=abc123xyz789

On the server (in session files):

/tmp/sess_abc123xyz789
user|a:1:{s:5:"email";s:16:"user@example.com";}

This is more secure than storing everything in cookies:

  • Cookies are limited to ~4KB
  • Cookies are sent with every request (bandwidth)
  • Cookies can be read/modified by the user (security risk)

Session Lifecycle in DALT.PHP

1. Session Starts (Entry Point)

// public/index.php
session_start();

2. Session Used (Throughout Request)

// Login controller
$_SESSION['user'] = ['email' => $email];

// Auth middleware
if (!isset($_SESSION['user'])) {
    redirect('/login');
}

// View
echo "Hello, " . $_SESSION['user']['email'];

3. Flash Data Added (On Errors)

// Validation exception handler
Session::flash('errors', $errors);
Session::flash('old', $oldInput);

4. Flash Data Cleaned (End of Request)

// public/index.php (last line)
Session::unflash();

Key Takeaways

  1. Sessions remember users - Essential for login, carts, flash messages
  2. Custom session names prevent collisions - Multiple local apps won't interfere
  3. Headers must come first - No output before session_start()
  4. Session ID in cookie, data on server - More secure than client-side storage
  5. Security is configured explicitly - HttpOnly, Secure, and SameSite protect against attacks

What's Good Here

✅ Unique session name per project (smart collision prevention)
✅ Session starts early, before any output
✅ Uses PHP's built-in session handling (battle-tested)
✅ Session data is server-side (more secure)
✅ Secure cookie parameters configured (HttpOnly, SameSite, Secure)
✅ Auto-detects HTTPS for secure flag
✅ Session cookie expires when browser closes (lifetime = 0)


Next, we'll look at how the framework bootstraps itself and loads the database.

On this page