Start · Sprachen · PHP · Referenz · eio_sendfile

eio_sendfile

Funktion

Überträgt Daten zwischen zwei Dateideskriptoren, ähnlich dem POSIX-Systemaufruf <code>sendfile()</code>, ohne Daten in den Userspace zu kopieren.

seit PHP 0.3.1 Kategorie: io

Signatur

eio_sendfile(mixed $out_fd, mixed $in_fd, int $offset, int $length, int $pri = EIO_PRI_DEFAULT, callable $callback = null, mixed $data = null): resource

Beschreibung

eio_sendfile() überträgt Daten direkt zwischen zwei Dateideskriptoren innerhalb des Kernels. Dadurch entfällt das aufwändige Kopieren von Daten in den Userspace und zurück — die Übertragung ist daher deutlich effizienter als ein manuelles fread()/fwrite()-Paar. Die Funktion gehört zur libeio-Erweiterung und arbeitet vollständig asynchron.

Typische Anwendungsfälle sind das schnelle Senden von Dateiinhalten über einen Socket (z. B. für einen HTTP-Server) oder das Kopieren größerer Dateimengen zwischen zwei geöffneten Dateideskriptoren, ohne die Applikation zu blockieren. Der Parameter offset gibt an, ab welcher Position in der Quelldatei gelesen wird; length bestimmt die Anzahl der zu übertragenden Bytes.

Das Ergebnis der asynchronen Operation wird über die callback-Funktion zurückgemeldet, die nach Abschluss der Übertragung aufgerufen wird. Der Callback erhält die übliche libeio-Signatur callback(mixed $data, int $result), wobei $result im Erfolgsfall die Anzahl der übertragenen Bytes ist oder -1 bei einem Fehler.

Die Funktion setzt voraus, dass die eio PECL-Erweiterung installiert und eine Event-Loop (z. B. über eio_event_loop()) aktiv ist. Sie ist besonders sinnvoll in I/O-intensiven, nicht-blockierenden Serveranwendungen.

Parameter

Name Typ Default Beschreibung
$out_fd Pflicht mixed Ziel-Dateideskriptor, in den die Daten geschrieben werden. Kann ein Stream-Ressource oder ein Integer-Dateideskriptor sein.
$in_fd Pflicht mixed Quell-Dateideskriptor, aus dem die Daten gelesen werden. Typischerweise eine geöffnete Datei.
$offset Pflicht int Startposition in Bytes innerhalb des Quell-Dateideskriptors in_fd, ab der die Übertragung beginnt.
$length Pflicht int Anzahl der Bytes, die aus dem Quell-Dateideskriptor übertragen werden sollen.
$pri int EIO_PRI_DEFAULT Priorität der asynchronen Anforderung. Mögliche Werte: EIO_PRI_DEFAULT, EIO_PRI_MIN, EIO_PRI_MAX.
$callback callable null Callback-Funktion, die nach Abschluss der Operation aufgerufen wird. Signatur: callback(mixed $data, int $result). $result enthält die Anzahl übertragener Bytes oder -1 bei Fehler.
$data mixed null Beliebige benutzerdefinierte Daten, die unverändert an den callback weitergegeben werden.

Rückgabewert

Typ
resource
Beschreibung
Gibt eine eio-Anforderungsressource zurück, die die asynchrone Operation repräsentiert, oder false bei einem Fehler.

Beispiele

Datei asynchron in einen Socket übertragen

<?php
// Voraussetzung: eio-Extension ist installiert

$inFile  = fopen('/var/www/html/large_file.bin', 'rb');
$outFile = fopen('/tmp/copy_of_large_file.bin', 'wb');

if (!$inFile || !$outFile) {
    die('Dateien konnten nicht geöffnet werden.');
}

$fileSize = filesize('/var/www/html/large_file.bin');

$req = eio_sendfile(
    $outFile,       // Ziel-Dateideskriptor
    $inFile,        // Quell-Dateideskriptor
    0,              // Offset: Beginn der Datei
    $fileSize,      // Länge: gesamte Datei übertragen
    EIO_PRI_DEFAULT,
    function ($data, $result) use ($inFile, $outFile) {
        if ($result === -1) {
            echo 'Fehler bei der Übertragung: ' . eio_get_last_error() . PHP_EOL;
        } else {
            echo "Erfolgreich {$result} Bytes übertragen." . PHP_EOL;
        }
        fclose($inFile);
        fclose($outFile);
    },
    null
);

// Event-Loop starten, bis alle Anforderungen abgeschlossen sind
eio_event_loop();
?>
Erfolgreich 1048576 Bytes übertragen.

Teilweise Übertragung ab einem bestimmten Offset

<?php
// Nur 512 Bytes ab Position 1024 übertragen

$inFile  = fopen('/var/log/syslog', 'rb');
$outFile = fopen('/tmp/syslog_excerpt.txt', 'wb');

eio_sendfile(
    $outFile,
    $inFile,
    1024,   // Übertragung startet ab Byte 1024
    512,    // Nur 512 Bytes übertragen
    EIO_PRI_DEFAULT,
    function ($data, $result) use ($inFile, $outFile) {
        if ($result >= 0) {
            echo "Ausschnitt ({$result} Bytes) erfolgreich geschrieben." . PHP_EOL;
        } else {
            echo 'Übertragungsfehler.' . PHP_EOL;
        }
        fclose($inFile);
        fclose($outFile);
    }
);

eio_event_loop();
?>
Ausschnitt (512 Bytes) erfolgreich geschrieben.

// Wichtig · Fallstricke

Plattformunterstützung: eio_sendfile() nutzt intern den nativen sendfile()-Systemaufruf, der unter Linux und macOS verfügbar ist, unter Windows jedoch nicht. Auf nicht unterstützten Systemen kann das Verhalten abweichen oder ein Fehler auftreten.

Event-Loop erforderlich: Da die Funktion asynchron arbeitet, muss eio_event_loop() oder ein kompatibler Event-Dispatcher (z. B. libevent) ausgeführt werden, damit der Callback tatsächlich aufgerufen wird. Ohne aktive Event-Loop bleibt die Operation ausstehend.

Fehlerbehandlung: Ein Rückgabewert von -1 im Callback signalisiert einen Fehler. Mit eio_get_last_error() kann die genaue Fehlerursache ermittelt werden. Stellen Sie sicher, dass die Dateideskriptoren gültig und geöffnet sind, bevor Sie die Funktion aufrufen.