A custom PHP session handler needs a valid new identifier when PHP starts or regenerates a session. Implement create_sid() in the handler object and return an ID generated by PHP; do not use a predictable value, request data, or a database auto-increment key.
Last updated: October 2, 2026.
<?php
final class DatabaseSessionHandler implements
SessionHandlerInterface,
SessionIdInterface,
SessionUpdateTimestampHandlerInterface
{
public function create_sid(): string
{
$id = session_create_id();
if ($id === false) {
throw new RuntimeException('Could not create a session ID.');
}
return $id;
}
public function validateId(string $id): bool
{
return $this->sessionExists($id);
}
// Implement open, close, read, write, destroy, gc,
// updateTimestamp, and sessionExists for your storage.
}session_create_id() follows the configured session-ID format. When a session is active, PHP documents it as collision-free for the current handler. Keep validateId() so strict mode can reject an unknown client-supplied ID.
Do not insert a row inside create_sid()
create_sid() generates an identifier; the normal handler lifecycle then calls read() and later write(). Let read() return an empty string when no row exists and let write() insert or update the row. Creating an empty record inside the ID generator complicates regeneration and can leave abandoned rows.
The PHP manual documents the callback contract in SessionIdInterface::create_sid() and the collision behavior of session_create_id().
Test strict mode and regeneration
Register the object with session_set_save_handler($handler, true), enable session.use_strict_mode, and test a new session, an existing session, an invented cookie value, regeneration, and concurrent requests. PHP’s accepted 8.6 deprecation RFC explains why create_sid() and validateId() are becoming required behavior.
Review secure PHP cookies, repeated login protection, and PHP function signatures when integrating the handler.