Signatur
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();
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;
});
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;
});
// 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.