Start · Sprachen · PHP · Referenz · Swoole\Timer

Swoole\Timer

Klasse

Verwaltet asynchrone Timer in Swoole; erlaubt das Ausführen von Callbacks nach einem Intervall oder einmalig nach einer Verzögerung.

seit PHP 4.0.0 Kategorie: misc

Signatur

class Swoole\Timer

Beschreibung

Swoole\Timer bietet eine statische API zum Erstellen und Verwalten von Timern innerhalb des Swoole-Event-Loop. Es gibt zwei grundlegende Betriebsmodi: wiederholende Timer (tick), die einen Callback in regelmäßigen Abständen ausführen, und einmalige Timer (after), die einen Callback genau einmal nach einer definierten Verzögerung aufrufen.

Timer laufen asynchron im Swoole-Coroutine- bzw. Event-Loop-Kontext und blockieren den Prozess nicht. Die Auflösung liegt bei mindestens 1 Millisekunde — Werte darunter erzeugen eine E_WARNING und der Timer wird nicht erstellt. Jeder Timer erhält eine eindeutige ID, mit der er über Swoole\Timer::clear() oder Swoole\Timer::clearAll() wieder entfernt werden kann.

Typische Einsatzgebiete sind periodische Hintergrundaufgaben (z. B. Cache-Invalidierung, Heartbeat-Signale), Timeouts für asynchrone Operationen sowie verzögerte Initialisierungen im Server-Kontext. Swoole\Timer ist nicht für den Einsatz außerhalb eines aktiven Event-Loops gedacht — in herkömmlichen synchronen PHP-Skripten ohne Swoole-Server hat er keine Wirkung.

Alle Methoden sind statisch; die Klasse wird nicht instanziiert. Die Timer-IDs sind prozesslokale Integer, die nach einem Worker-Reload zurückgesetzt werden können.

Beispiele

Wiederholender Timer mit tick()

<?php
// Swoole HTTP-Server mit einem periodischen Timer
$server = new Swoole\HTTP\Server('0.0.0.0', 9501);

$server->on('start', function (Swoole\HTTP\Server $server) {
    // Callback alle 2000 ms (2 Sekunden) ausführen
    $timerId = Swoole\Timer::tick(2000, function (int $timerId) {
        echo "[" . date('H:i:s') . "] Heartbeat – Timer-ID: {$timerId}" . PHP_EOL;
    });

    echo "Timer gestartet mit ID: {$timerId}" . PHP_EOL;
});

$server->on('request', function ($request, $response) {
    $response->end('<h1>Hallo Swoole</h1>');
});

$server->start();
Timer gestartet mit ID: 1 [12:00:02] Heartbeat – Timer-ID: 1 [12:00:04] Heartbeat – Timer-ID: 1 ...

Einmaliger verzögerter Timer mit after() und manuellem Abbruch

<?php
Swoole\Coroutine\run(function () {
    echo "Starte verzögerten Timer..." . PHP_EOL;

    // Einmalig nach 1500 ms ausführen
    $timerId = Swoole\Timer::after(1500, function () {
        echo "Timer abgelaufen! Einmalige Aufgabe erledigt." . PHP_EOL;
    });

    echo "Timer-ID: {$timerId}" . PHP_EOL;

    // Beispiel: Timer vorzeitig löschen (hier nach 500 ms)
    Swoole\Coroutine::sleep(0.5);
    $cleared = Swoole\Timer::clear($timerId);
    echo "Timer gelöscht: " . ($cleared ? 'ja' : 'nein') . PHP_EOL;

    // Alle noch laufenden Timer ausgeben
    $list = Swoole\Timer::list();
    echo "Verbleibende Timer: " . count(iterator_to_array($list)) . PHP_EOL;
});
Starte verzögerten Timer... Timer-ID: 1 Timer gelöscht: ja Verbleibende Timer: 0

Alle Timer auf einmal löschen mit clearAll()

<?php
Swoole\Coroutine\run(function () {
    // Mehrere Ticker anlegen
    Swoole\Timer::tick(1000, function () { echo "Timer A\n"; });
    Swoole\Timer::tick(2000, function () { echo "Timer B\n"; });
    Swoole\Timer::tick(3000, function () { echo "Timer C\n"; });

    $list = Swoole\Timer::list();
    $ids  = iterator_to_array($list);
    echo "Aktive Timer vor clearAll: " . count($ids) . PHP_EOL;

    // Alle Timer stoppen
    Swoole\Timer::clearAll();

    $list = Swoole\Timer::list();
    echo "Aktive Timer nach clearAll: " . count(iterator_to_array($list)) . PHP_EOL;
});
Aktive Timer vor clearAll: 3 Aktive Timer nach clearAll: 0

// Wichtig · Fallstricke

Mindest-Intervall: Werte kleiner als 1 ms (also < 1) erzeugen eine E_WARNING und der Timer wird nicht erstellt. Die Rückgabe ist in diesem Fall false.

Kontext-Einschränkung: Timer funktionieren nur innerhalb eines laufenden Swoole-Event-Loops (Server-Callbacks, Coroutinen etc.). Ein Aufruf in einem normalen synchronen PHP-Skript ohne aktiven Loop führt zu keiner Ausführung des Callbacks.

Worker-Neustart: Beim Neustart von Worker-Prozessen werden alle Timer des alten Prozesses automatisch ungültig. Timer müssen im neuen Worker-Prozess erneut registriert werden (z. B. im workerStart-Event).

Coroutine-Sicherheit: Swoole\Timer::tick() und after() sind Coroutine-sicher, sollten aber nicht mit blockierenden Operationen innerhalb des Callbacks kombiniert werden — stattdessen eine neue Coroutine mit go() starten.