umityatarkalkmaz / session
Thin wrapper over PHP sessions with safe cookie flags and no silent no-ops
Requires
- php: >=8.2
- ext-session: *
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.5 || ^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A thin wrapper over PHP's session functions. It starts sessions with cookie flags that are safe by default, and refuses to run any operation on a session that is not actually running.
Requirements
PHP 8.2 or newer, with ext-session.
Installation
composer require umityatarkalkmaz/session
Usage
use UmitYatarkalkmaz\Session; Session::start('MySession', timeoutMinutes: 60); Session::set('username', 'Ümit Yatarkalkmaz'); if (Session::has('username')) { echo Session::get('username'); } Session::remove('username'); Session::destroy();
Starting
Session::start( ?string $name = null, ?int $timeoutMinutes = null, ?bool $secure = null, string $sameSite = 'Lax', ): void
Cookie parameters can only be set before a session starts, which is why the
timeout is an argument here instead of a separate call. The cookie is always
HttpOnly, defaults to SameSite=Lax, and is marked Secure automatically
when the current request is over HTTPS — pass secure: true explicitly when
PHP cannot see that, such as behind a TLS-terminating proxy. session.use_strict_mode
and session.use_only_cookies are enabled, so a session id the server never
issued is rejected.
$timeoutMinutes sets both the cookie lifetime and session.gc_maxlifetime.
Leave it null for a cookie that lasts until the browser closes.
session.gc_maxlifetime is a process-global setting, not a per-session one. On
a shared PHP-FPM pool the last start() to run wins for every request the
worker serves afterwards, and with the default files handler the garbage
collector sweeps one save path, so a short-lived session in one application can
expire the server-side data of a longer-lived session in another. Give each
application its own session.save_path — or its own pool — when the timeouts
differ.
start() throws RuntimeException if a session is already running or if output
has already been sent, and InvalidArgumentException for an unusable session
name, a non-positive timeout, or an unknown SameSite value. A name of digits
only is rejected too, because PHP itself refuses one.
After login
Session::regenerate();
Issues a new session id and keeps the data. Call it whenever the privilege level changes — right after a successful login above all — so a fixated id becomes useless.
Reading and writing
set(), get(), has() and remove() all throw RuntimeException when no
session is running, rather than quietly reading and writing a plain array whose
contents are discarded at the end of the request.
get(string $key, mixed $default = null) returns $default for an absent key.
Ending
Session::destroy();
Clears the data, ends the session, and expires the session cookie, so the browser stops presenting an id for a session that no longer exists.
Session::close();
Writes the data and releases the session without destroying it. PHP holds the
session file locked for the whole request, so concurrent requests from the same
browser queue behind each other; call close() as soon as a long-running
request stops writing to the session. Reading afterwards requires start()
again. Like every other operation, it throws RuntimeException when no session
is running.
License
MIT. See LICENSE.