Signatur
Beschreibung
ftp_nb_fget() ist die nicht-blockierende Variante von ftp_fget(). Statt den PHP-Prozess während des gesamten Downloads anzuhalten, gibt die Funktion sofort einen Status-Code zurück (FTP_MOREDATA, FTP_FINISHED oder FTP_FAILED), sodass zwischendurch anderer Code ausgeführt werden kann.
Um den Transfer fortzuführen, muss ftp_nb_continue() in einer Schleife aufgerufen werden, bis der Rückgabewert nicht mehr FTP_MOREDATA ist. Dieses Muster eignet sich besonders, wenn während des Downloads Fortschrittsanzeigen aktualisiert, Log-Einträge geschrieben oder mehrere Transfers parallel koordiniert werden sollen.
Der Parameter $stream erwartet eine bereits mit fopen() geöffnete Datei-Ressource. Im Gegensatz zu ftp_nb_get(), das einen Dateinamen entgegennimmt, gibt dies dem Aufrufer volle Kontrolle über den Datei-Handle (z. B. für Speicher-Streams oder temporäre Dateien). Der $offset-Parameter ermöglicht das Fortsetzen unterbrochener Downloads.
Der Transfer-Modus sollte für Binärdateien FTP_BINARY und für Textdateien FTP_ASCII sein; bei FTP_ASCII werden Zeilenenden plattformabhängig konvertiert.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $ftp Pflicht | FTP\Connection | Eine aktive FTP-Verbindung, wie sie von ftp_connect() oder ftp_ssl_connect() zurückgegeben wird. |
|
| $stream Pflicht | resource | Eine bereits mit fopen() geöffnete, beschreibbare Datei-Ressource, in die der Dateiinhalt geschrieben wird. |
|
| $remote_filename Pflicht | string | Der Pfad zur Datei auf dem FTP-Server, die heruntergeladen werden soll. | |
| $mode | int | FTP_BINARY | Transfer-Modus: FTP_BINARY für Binärdaten oder FTP_ASCII für Textdateien mit Zeilenenden-Konvertierung. |
| $offset | int | 0 | Byte-Position auf dem Server, ab der der Download beginnen soll. Nützlich zum Fortsetzen unterbrochener Transfers. |
Rückgabewert
FTP_MOREDATA zurück, solange der Transfer läuft; FTP_FINISHED bei erfolgreichem Abschluss; FTP_FAILED bei einem Fehler. Um den Transfer weiterzuführen, muss ftp_nb_continue() in einer Schleife aufgerufen werden.Beispiele
Einfacher nicht-blockierender Download mit Fortschrittsausgabe
<?php
$ftp = ftp_connect('ftp.example.com');
ftp_login($ftp, 'benutzer', 'geheim');
ftp_pasv($ftp, true);
$lokale_datei = fopen('/tmp/download.zip', 'wb');
if ($lokale_datei === false) {
die('Lokale Datei konnte nicht geöffnet werden.');
}
$status = ftp_nb_fget($ftp, $lokale_datei, '/remote/archiv.zip', FTP_BINARY);
while ($status === FTP_MOREDATA) {
// Hier kann anderer Code ausgeführt werden, z. B. Fortschritt loggen
echo '.';
$status = ftp_nb_continue($ftp);
}
if ($status === FTP_FINISHED) {
echo PHP_EOL . 'Download erfolgreich abgeschlossen.';
} else {
echo PHP_EOL . 'Download fehlgeschlagen.';
}
fclose($lokale_datei);
ftp_close($ftp);
Download in einen temporären Speicher-Stream
<?php
$ftp = ftp_connect('ftp.example.com');
ftp_login($ftp, 'benutzer', 'geheim');
ftp_pasv($ftp, true);
// Temporären In-Memory-Stream verwenden
$speicher = fopen('php://temp', 'r+b');
$status = ftp_nb_fget($ftp, $speicher, '/remote/config.txt', FTP_ASCII);
while ($status === FTP_MOREDATA) {
$status = ftp_nb_continue($ftp);
}
if ($status === FTP_FINISHED) {
rewind($speicher);
$inhalt = stream_get_contents($speicher);
echo 'Dateiinhalt (' . strlen($inhalt) . ' Bytes) erfolgreich geladen.';
} else {
echo 'Fehler beim Laden der Datei.';
}
fclose($speicher);
ftp_close($ftp);
// Wichtig · Fallstricke
Passive-Mode-Empfehlung: Viele Firewall-Konfigurationen erfordern den passiven Modus. Rufe vor dem Transfer ftp_pasv($ftp, true) auf, um Verbindungsprobleme zu vermeiden.
PHP 8.1: Ab PHP 8.1 ist der Typ des $ftp-Parameters FTP\Connection statt resource. Code, der is_resource() darauf aufruft, muss ggf. angepasst werden.
Fehlerbehandlung: Bei einem Rückgabewert von FTP_FAILED sollte die Verbindung geprüft und der lokale Datei-Handle explizit geschlossen werden, um Ressourcen-Leaks zu verhindern. Unvollständige lokale Dateien sollten gelöscht werden.
Blocking vs. Non-Blocking: In klassischen synchronen PHP-Skripten bietet der nicht-blockierende Modus nur dann einen echten Vorteil, wenn innerhalb der Warteschleife sinnvolle Arbeit geleistet wird. Andernfalls ist ftp_fget() einfacher und ausreichend.