Signatur
Beschreibung
EvPeriodic ist ein Watcher aus der ev-Erweiterung, der Callbacks zu periodischen oder einmaligen Zeitpunkten auslöst. Im Gegensatz zu EvTimer orientiert er sich an der Wanduhrzeit und nicht an einer relativen Verzögerung ab dem Startzeitpunkt – er gleicht Systemzeit-Sprünge (z. B. durch NTP) automatisch aus.
Der Watcher unterstützt drei Betriebsmodi: Im Absolute-Mode (Interval = 0) löst er genau einmal zum angegebenen Offset-Zeitpunkt aus. Im Interval-Mode löst er periodisch alle interval Sekunden aus, wobei der erste Auslösezeitpunkt aus offset + N * interval (N ∈ ℤ) berechnet wird, sodass z. B. immer zur vollen Stunde ausgelöst werden kann. Im Manual-Mode wird ein benutzerdefinierter Reschedule-Callback verwendet, der maximale Flexibilität bietet.
Typische Anwendungsfälle sind Hintergrundaufgaben wie tägliche Bereinigungsläufe, stündliche Statistikauswertungen oder andere zeitgesteuerte Jobs innerhalb einer Event-Loop, die robust gegenüber Systemzeit-Korrekturen sein sollen.
EvPeriodic ist Teil der PECL-Erweiterung ev und steht zur Verfügung, sobald diese installiert ist. Die Klasse erbt allgemeine Watcher-Methoden wie start(), stop(), keepalive() und invoke() von EvWatcher.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $offset Pflicht | float | Im Interval-Mode: Phasen-Offset in Sekunden (0 bis interval), bestimmt den Startzeitpunkt innerhalb eines Intervalls. Im Absolute-Mode: absoluter Unix-Timestamp des einmaligen Auslösezeitpunkts. | |
| $interval Pflicht | float | Wiederholungsintervall in Sekunden. Muss ≥ 0 sein. Wird 0 übergeben, läuft der Watcher im Absolute-Mode (einmaliger Auslöser). | |
| $reschedule_cb Pflicht | callable|null | null | Optionaler Reschedule-Callback für den Manual-Mode. Erhält den Watcher und den aktuellen Zeitstempel und muss den nächsten Auslösezeitpunkt (Unix-Timestamp als float) zurückgeben. Wird null übergeben, ist der Manual-Mode deaktiviert. |
| $callback Pflicht | callable | Callback-Funktion, die beim Auslösen des Watchers aufgerufen wird. Erhält den Watcher als ersten und ein Bitmask-Ereignis-Flag als zweiten Parameter. | |
| $data | mixed | null | Beliebige benutzerdefinierte Daten, die dem Watcher zugeordnet und über $watcher->data zugänglich sind. |
| $priority | int | 0 | Priorität des Watchers als Ganzzahl. Höhere Werte bedeuten höhere Priorität. Erlaubter Bereich: Ev::MINPRI bis Ev::MAXPRI. |
Beispiele
Periodischer Watcher – jede volle Minute
<?php
// Löst jede Minute genau zur vollen Minute aus (offset=0, interval=60)
$periodic = new EvPeriodic(0, 60, null, function (EvPeriodic $watcher, int $events) {
echo 'Ausgelöst um: ' . date('H:i:s') . PHP_EOL;
});
Ev::run();
Absolute Mode – einmaliger Auslöser in 5 Sekunden
<?php
// Absolute Mode: interval=0, offset = gewünschter Unix-Timestamp
$triggerAt = microtime(true) + 5.0;
$periodic = new EvPeriodic($triggerAt, 0, null, function (EvPeriodic $watcher, int $events) {
echo 'Einmaliger Callback ausgelöst um: ' . date('H:i:s') . PHP_EOL;
$watcher->stop(); // Watcher nach einmaliger Ausführung stoppen
});
Ev::run();
Manual-Mode mit Reschedule-Callback
<?php
// Manual-Mode: nächster Auslösezeitpunkt wird dynamisch berechnet
// Hier: alle 10 Sekunden, aber nur zwischen 08:00 und 18:00 Uhr
$periodic = new EvPeriodic(0, 0, function (EvPeriodic $watcher, float $now): float {
$next = $now + 10.0;
$hour = (int) date('G', (int) $next);
// Außerhalb der Geschäftszeiten auf nächsten Morgen verschieben
if ($hour < 8 || $hour >= 18) {
$tomorrow = mktime(8, 0, 0, (int)date('n'), (int)date('j') + 1);
return (float) $tomorrow;
}
return $next;
}, function (EvPeriodic $watcher, int $events) {
echo 'Job ausgeführt um ' . date('H:i:s') . PHP_EOL;
});
Ev::run();
// Wichtig · Fallstricke
Unterschied zu EvTimer: EvTimer misst relative Zeit ab dem Start, EvPeriodic hingegen arbeitet mit absoluten Wanduhrzeiten und passt sich automatisch an NTP-Korrekturen oder Systemzeit-Sprünge an. Für zeitzonengenaue, stabile Cron-artige Aufgaben ist EvPeriodic deshalb besser geeignet.
Reschedule-Callback Sicherheit: Der Reschedule-Callback muss immer einen Wert strikt größer als das übergebene $now zurückgeben. Wird ein kleinerer oder gleicher Wert zurückgegeben, führt dies zu einer Endlosschleife und hängt die Event-Loop dauerhaft auf.
Voraussetzung: Die PECL-Erweiterung ev muss installiert sein (pecl install ev). Sie ist nicht Teil der PHP-Standardinstallation.
Eigenschaften wie $watcher->at liefern den tatsächlichen nächsten geplanten Auslösezeitpunkt als Unix-Timestamp und können zur Diagnose genutzt werden.