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