Start · Sprachen · PHP · Referenz · EventBase

EventBase

Klasse

Repräsentiert die <code>event_base</code>-Struktur von libevent und bildet den zentralen Event-Loop, der Events verwaltet und per Polling aktive ermittelt.

seit PHP 1.5.0 Kategorie: io

Signatur

class EventBase

Beschreibung

EventBase ist das Herzstück der PHP-Erweiterung Event (PECL). Sie kapselt die native event_base-Struktur von libevent und stellt den sogenannten Event-Loop bereit, der wiederholt auf aktive Events (I/O, Timer, Signale) wartet und die zugehörigen Callbacks aufruft.

Beim Erzeugen einer EventBase-Instanz wählt libevent automatisch das effizienteste verfügbare Backend des Betriebssystems (z. B. epoll unter Linux, kqueue unter BSD oder select als Fallback). Über ein optionales EventConfig-Objekt kann das Backend und weitere Einstellungen explizit gesteuert werden.

Alle Event-Objekte werden an eine EventBase gebunden, bevor sie aktiviert werden können. Die Methode EventBase::dispatch() startet den Loop und blockiert, bis keine Events mehr aktiv sind oder EventBase::exit() bzw. EventBase::stop() aufgerufen wird. Für Server-Anwendungen, Long-Running-Prozesse und asynchrone I/O-Aufgaben ist diese Klasse der zentrale Einstiegspunkt.

Typischerweise wird pro Prozess (oder Thread) genau eine EventBase-Instanz angelegt. Die Klasse ist nicht thread-sicher; in Multi-Thread-Umgebungen sollte jeder Thread seine eigene Instanz verwenden.

Parameter

Name Typ Default Beschreibung
$cfg EventConfig|null null Optionales EventConfig-Objekt, mit dem Backend-Methode, Features und weitere Optionen des Event-Loops konfiguriert werden können. Wird null übergeben oder der Parameter weggelassen, wählt libevent automatisch das optimale Backend.

Rückgabewert

Typ

Beispiele

Einfacher Event-Loop mit Timer

<?php
// EventBase ohne spezielle Konfiguration erstellen
$base = new EventBase();

// Timer-Event: feuert einmalig nach 1 Sekunde
$event = new Event($base, -1, Event::TIMEOUT, function () use ($base) {
    echo "Timer ausgelöst!" . PHP_EOL;
    $base->exit(); // Loop beenden
});

$event->add(1.0); // nach 1 Sekunde auslösen

echo "Loop startet..." . PHP_EOL;
$base->dispatch(); // blockiert bis exit() aufgerufen wird
echo "Loop beendet." . PHP_EOL;
Loop startet... Timer ausgelöst! Loop beendet.

EventBase mit EventConfig (Backend einschränken)

<?php
// Nur poll oder select als Backend erlauben (kein epoll)
$cfg = new EventConfig();
$cfg->avoidMethod('epoll');
$cfg->avoidMethod('kqueue');

$base = new EventBase($cfg);
echo "Verwendetes Backend: " . $base->getMethod() . PHP_EOL;

// Lesbarkeit der aktiven Features prüfen
$features = $base->getFeatures();
echo "Features-Bitmaske: " . $features . PHP_EOL;

unset($base, $cfg);
Verwendetes Backend: poll Features-Bitmaske: 0

Asynchrones Lesen von einem Socket

<?php
$base = new EventBase();

// Nicht-blockierenden Server-Socket erstellen
$server = stream_socket_server('tcp://0.0.0.0:8080', $errno, $errstr);
stream_set_blocking($server, false);

$acceptEvent = new Event($base, $server, Event::READ | Event::PERSIST, function ($fd) use ($base) {
    $conn = stream_socket_accept($fd);
    fwrite($conn, "HTTP/1.1 200 OK\r\nContent-Length: 13\r\n\r\nHello, World!");
    fclose($conn);
    echo "Verbindung bedient." . PHP_EOL;
    // Nach einer Anfrage beenden (Demo)
    $base->exit();
});

$acceptEvent->add();
echo "Warte auf Verbindungen auf Port 8080 ..." . PHP_EOL;
$base->dispatch();
fclose($server);
Warte auf Verbindungen auf Port 8080 ...

// Wichtig · Fallstricke

Thread-Sicherheit: EventBase ist nicht thread-sicher. Dieselbe Instanz darf nicht gleichzeitig aus mehreren Threads verwendet werden. Für Multi-Threading muss jeder Thread eine eigene EventBase-Instanz anlegen.

Ressourcen-Management: Alle Event-Objekte, die an eine EventBase gebunden sind, sollten vor dem Zerstören der EventBase explizit über Event::del() entfernt und freigegeben werden, um Memory-Leaks oder Use-after-free-Fehler zu vermeiden.

Abhängigkeit: Die Klasse steht nur zur Verfügung, wenn die PECL-Erweiterung event installiert ist (pecl install event). Sie ist nicht mit der älteren libevent-Erweiterung identisch.

Loop-Abbruch: EventBase::exit() beendet den Loop nach dem aktuellen Callback-Durchlauf, während EventBase::stop() ihn sofort unterbricht. Für Graceful-Shutdown-Szenarien ist exit() in der Regel die bessere Wahl.