Start · Sprachen · PHP · Referenz · SessionUpdateTimestampHandlerInterface

SessionUpdateTimestampHandlerInterface

Interface

Schnittstelle für benutzerdefinierte Session-Handler, die das Prüfen und Aktualisieren des Session-Zeitstempels ermöglichen.

seit PHP 7.0.0 Kategorie: http

Signatur

interface SessionUpdateTimestampHandlerInterface

Beschreibung

SessionUpdateTimestampHandlerInterface ist eine ergänzende Schnittstelle zu SessionHandlerInterface. Sie definiert zwei optionale Methoden, die es einem benutzerdefinierten Session-Handler ermöglichen, den Zeitstempel einer Session zu prüfen und zu aktualisieren, ohne die Session-Daten neu zu schreiben.

Diese Schnittstelle ist besonders nützlich, wenn Sessions auf der Serverseite mit einem eigenen Speicher-Backend (z. B. Redis, Datenbank) verwaltet werden und dabei eine effiziente Verlängerung der Session-Lebensdauer ohne unnötiges Schreiben der vollständigen Session-Daten gewünscht ist. PHP ruft intern validateId() auf, um zu prüfen, ob eine Session-ID gültig und aktuell ist, und updateTimestamp(), um den Zeitstempel zu aktualisieren ohne die Daten zu schreiben.

Ohne diese Schnittstelle würde PHP bei jedem Request die gesamten Session-Daten neu schreiben, was bei häufigen Anfragen oder großen Session-Daten zu erheblichem Overhead führen kann. Durch die Implementierung dieser Schnittstelle zusammen mit SessionHandlerInterface kann das Verhalten gezielt optimiert werden.

Ein eigener Session-Handler wird über session_set_save_handler() registriert und muss dabei sowohl SessionHandlerInterface als auch – für die Zeitstempel-Funktionalität – SessionUpdateTimestampHandlerInterface implementieren.

Beispiele

Benutzerdefinierter Session-Handler mit Zeitstempel-Unterstützung

<?php
class RedisSessionHandler implements SessionHandlerInterface, SessionUpdateTimestampHandlerInterface
{
    private Redis $redis;
    private int $ttl;

    public function __construct(Redis $redis, int $ttl = 1800)
    {
        $this->redis = $redis;
        $this->ttl   = $ttl;
    }

    public function open(string $path, string $name): bool
    {
        return true;
    }

    public function close(): bool
    {
        return true;
    }

    public function read(string $id): string|false
    {
        return $this->redis->get('sess:' . $id) ?: '';
    }

    public function write(string $id, string $data): bool
    {
        return $this->redis->setex('sess:' . $id, $this->ttl, $data);
    }

    public function destroy(string $id): bool
    {
        $this->redis->del('sess:' . $id);
        return true;
    }

    public function gc(int $max_lifetime): int|false
    {
        // Redis übernimmt das Ablaufen automatisch via TTL
        return 0;
    }

    // --- SessionUpdateTimestampHandlerInterface ---

    /**
     * Prüft, ob eine Session-ID existiert und noch gültig ist.
     */
    public function validateId(string $id): bool
    {
        return (bool) $this->redis->exists('sess:' . $id);
    }

    /**
     * Verlängert die TTL der Session, ohne die Daten neu zu schreiben.
     */
    public function updateTimestamp(string $id, string $data): bool
    {
        return (bool) $this->redis->expire('sess:' . $id, $this->ttl);
    }
}

$redis   = new Redis();
$redis->connect('127.0.0.1', 6379);

$handler = new RedisSessionHandler($redis, 3600);
session_set_save_handler($handler, true);
session_start();

$_SESSION['user'] = 'Max';
echo 'Session gestartet für: ' . $_SESSION['user'];
Session gestartet für: Max

Einfache In-Memory-Implementierung zum Testen

<?php
class ArraySessionHandler implements SessionHandlerInterface, SessionUpdateTimestampHandlerInterface
{
    private array $store     = [];
    private array $timestamps = [];

    public function open(string $path, string $name): bool  { return true; }
    public function close(): bool                           { return true; }

    public function read(string $id): string|false
    {
        return $this->store[$id] ?? '';
    }

    public function write(string $id, string $data): bool
    {
        $this->store[$id]      = $data;
        $this->timestamps[$id] = time();
        return true;
    }

    public function destroy(string $id): bool
    {
        unset($this->store[$id], $this->timestamps[$id]);
        return true;
    }

    public function gc(int $max_lifetime): int|false
    {
        $expired = 0;
        $cutoff  = time() - $max_lifetime;
        foreach ($this->timestamps as $id => $ts) {
            if ($ts < $cutoff) {
                $this->destroy($id);
                $expired++;
            }
        }
        return $expired;
    }

    public function validateId(string $id): bool
    {
        return isset($this->store[$id]);
    }

    public function updateTimestamp(string $id, string $data): bool
    {
        if (isset($this->timestamps[$id])) {
            $this->timestamps[$id] = time();
            return true;
        }
        return false;
    }
}

$handler = new ArraySessionHandler();
session_set_save_handler($handler, true);
session_start();
$_SESSION['test'] = 42;
echo 'Session-Wert: ' . $_SESSION['test'];
Session-Wert: 42

// Wichtig · Fallstricke

Sicherheitshinweis: Stellen Sie sicher, dass validateId() Session-IDs strikt validiert. Eine fehlerhafte Implementierung, die ungültige oder abgelaufene IDs akzeptiert, kann zu Session-Fixation- oder Replay-Angriffen führen.

Zusammenspiel mit session.lazy_write: Wenn die PHP-INI-Option session.lazy_write aktiviert ist (Standard seit PHP 7.0), ruft PHP updateTimestamp() auf, wenn sich die Session-Daten nicht geändert haben, anstatt write(). Dies reduziert unnötige Schreiboperationen erheblich.

Achtung: Diese Schnittstelle muss immer zusammen mit SessionHandlerInterface implementiert werden. Allein reicht sie nicht aus, um einen vollständigen Session-Handler bereitzustellen.