ftp_nb_continue()
Die Funktion ftp_nb_continue() ist eine in PHP eingebaute Funktion, die eine asynchrone FTP-Operation fortsetzt. Die Funktion nimmt einen Parameter entgegen:
Was ist ftp_nb_continue()?
ftp_nb_continue() ist eine in PHP eingebaute Funktion, die eine nicht-blockierende FTP-Dateiübertragung fortsetzt, die zuvor gestartet wurde. Das nb im Namen steht für non-blocking: Anstatt das Skript einzufrieren, bis eine ganze Datei hochgeladen oder heruntergeladen ist, geben die nicht-blockierenden FTP-Funktionen nach jedem Datenpaket die Kontrolle zurück, sodass das Skript in der Zwischenzeit andere Aufgaben erledigen kann.
Diese Seite behandelt, was die Funktion zurückgibt, wie die nicht-blockierende Übertragungsschleife funktioniert, wie Fehler behandelt werden und welche häufigen Fallstricke es gibt.
Wie nicht-blockierende Übertragungen funktionieren
Eine normale Übertragung wie ftp_get() blockiert: PHP wartet auf die gesamte Datei, bevor die nächste Zeile ausgeführt wird. Die nicht-blockierende Familie — ftp_nb_get(), ftp_nb_put(), ftp_nb_fget() und ftp_nb_fput() — startet die Übertragung und kehrt sofort zurück. Anschließend ruft man ftp_nb_continue() wiederholt auf, um die Übertragung stückweise voranzutreiben, bis gemeldet wird, dass sie abgeschlossen ist.
Die Funktion gibt eine von drei Konstanten zurück:
| Konstante | Bedeutung |
|---|---|
FTP_MOREDATA | Die Übertragung läuft noch — ftp_nb_continue() erneut aufrufen. |
FTP_FINISHED | Die Übertragung wurde erfolgreich abgeschlossen — Schleife beenden. |
FTP_FAILED | Die Übertragung ist fehlgeschlagen — Fehler behandeln und abbrechen. |
Hinweis: Die Startfunktion (
ftp_nb_get()usw.) gibt dieselben Konstanten zurück, daher muss die Schleifenlogik berücksichtigen, dass die Übertragung bereits beim ersten Aufruf abgeschlossen sein kann.
Syntax von ftp_nb_continue()
ftp_nb_continue(resource $ftp): intSie nimmt einen einzigen Parameter entgegen, $ftp: den Verbindungsbezeichner, der von ftp_connect() oder ftp_ssl_connect() zurückgegeben wird.
PHP 8.1+: Die Verbindung ist jetzt ein
FTP\Connection-Objekt statt einerresource, aber der Code muss nicht geändert werden — man übergibt einfach weiterhin den Wert, der vonftp_connect()zurückgegeben wurde.
Verwendung von ftp_nb_continue()
Zuerst wird eine nicht-blockierende Übertragung gestartet, dann wird sie mit einer Schleife zum Abschluss gebracht:
<?php
// Open the connection and log in
$ftp = ftp_connect('ftp.example.com');
ftp_login($ftp, 'username', 'password');
ftp_pasv($ftp, true); // passive mode is usually required behind firewalls
// Start a non-blocking download: local_file <- remote_file
$state = ftp_nb_get($ftp, 'local_file.txt', 'remote_file.txt', FTP_BINARY);
// Drive the transfer forward until it finishes or fails
while ($state === FTP_MOREDATA) {
// You can do other work here while the file streams in
$state = ftp_nb_continue($ftp);
}
if ($state === FTP_FINISHED) {
echo "Download complete.\n";
} else {
echo "Download failed.\n";
}
ftp_close($ftp);Zu beachten ist die Reihenfolge der Argumente bei ftp_nb_get(): Sie lautet (connection, local_file, remote_file, mode) — das lokale Ziel kommt vor der entfernten Quelle.
Fehlerbehandlung
Stets den Rückgabewert bei jeder Iteration prüfen. Wenn ftp_nb_continue() FTP_FAILED zurückgibt, ist die Übertragung unterbrochen, und es sollte abgebrochen und der Fehler gemeldet werden, anstatt endlos zu schleifen:
<?php
$state = ftp_nb_get($ftp, 'local_file.txt', 'remote_file.txt', FTP_BINARY);
while ($state === FTP_MOREDATA) {
$state = ftp_nb_continue($ftp);
}
switch ($state) {
case FTP_FINISHED:
echo "Transfer succeeded.\n";
break;
case FTP_FAILED:
echo "Transfer failed.\n";
break;
}Da die Schleifenbedingung === FTP_MOREDATA ist, wird sie sowohl bei FTP_FINISHED als auch bei FTP_FAILED automatisch beendet — der anschließende switch zeigt dann, was eingetreten ist.
Häufige Fallstricke
- Den Rückgabewert der Startfunktion vergessen zu prüfen. Eine kleine Datei kann bereits während
ftp_nb_get()selbst fertig werden undFTP_FINISHEDzurückgeben, bevor die Schleife überhaupt läuft. Den Rückgabewert wie oben$statezuzuweisen, behandelt diesen Fall korrekt. ftp_nb_continue()ohne aktive Übertragung aufrufen. Die Funktion funktioniert nur, solange eine nicht-blockierende Operation aussteht; andernfalls gibt sieFTP_FAILEDzurück.- Eine leere Warteschleife. Der ganze Sinn von nicht-blockierendem FTP ist es, zwischen den Aufrufen nützliche Arbeit zu erledigen. Eine leere
while-Schleife wartet nur aktiv und bietet keinen Vorteil gegenüber dem blockierendenftp_get(). - Passivmodus. Hinter einer Firewall oder NAT ist
ftp_pasv()in der Regel auftruezu setzen, bevor die Übertragung gestartet wird.
Fazit
ftp_nb_continue() setzt eine nicht-blockierende FTP-Übertragung fort, die mit ftp_nb_get(), ftp_nb_put(), ftp_nb_fget() oder ftp_nb_fput() gestartet wurde. In einer Schleife aufrufen, solange FTP_MOREDATA zurückgegeben wird, bei FTP_FINISHED stoppen und FTP_FAILED behandeln — so bleibt das Skript reaktionsfähig, während Dateien im Hintergrund übertragen werden.