Start · Sprachen · PHP · Referenz · EvPeriodic

EvPeriodic

Klasse

Löst wiederkehrend zu bestimmten Zeitpunkten aus, unabhängig von Sprüngen der Systemzeit.

Kategorie: io

Signatur

class EvPeriodic extends EvWatcher

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();
Ausgelöst um: 14:03:00 Ausgelöst um: 14:04:00 ...

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();
Einmaliger Callback ausgelöst um: 14:03:05

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();
Job ausgeführt um 10:00:00 Job ausgeführt um 10:00:10 ...

// 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.