ftp_fget()
Die PHP-Funktion ftp_fget() lädt eine Datei vom FTP-Server und schreibt sie in ein bereits geöffnetes lokales Datei-Handle.
Was ist ftp_fget()?
ftp_fget() lädt eine Datei von einem FTP-Server herunter und schreibt sie in ein bereits geöffnetes lokales Datei-Handle. Dies ist der wesentliche Unterschied zu ftp_get(): ftp_get() nimmt einen lokalen Pfad und erstellt die Datei für Sie, während ftp_fget() eine offene Datei-Ressource entgegennimmt (den von fopen() zurückgegebenen Wert). Da Sie das Handle selbst kontrollieren, ist ftp_fget() praktisch, wenn Sie in einen Stream schreiben möchten, der keine einfache Datei ist — einen temporären Stream (php://temp), einen In-Memory-Puffer oder ein mit fseek() positioniertes Handle.
Diese Seite behandelt die Signatur der Funktion, einen vollständigen funktionierenden Download, die Wahl eines Übertragungsmodus, das Fortsetzen eines unterbrochenen Downloads sowie die Fehlerbehandlung, die Sie in echtem Code benötigen.
Die prozedurale FTP-Erweiterung ist weiterhin Teil von PHP. Ab PHP 8.1 ist die Verbindung ein
FTP\Connection-Objekt statt einerresource, aber der Code, den Sie schreiben, bleibt unverändert. Für verschlüsselte Übertragungen verwenden Sieftp_ssl_connect()anstelle vonftp_connect().
Syntax von ftp_fget()
ftp_fget(
FTP\Connection $ftp,
resource $stream,
string $remote_filename,
int $mode = FTP_BINARY,
int $offset = 0
): bool| Parameter | Beschreibung |
|---|---|
$ftp | Die von ftp_connect() zurückgegebene Verbindung (und mit ftp_login() authentifiziert). |
$stream | Ein offener lokaler Dateizeiger, in den die heruntergeladenen Daten geschrieben werden. Er muss zum Schreiben geöffnet sein ('w', 'w+', 'a' usw.). |
$remote_filename | Pfad zur Datei auf dem FTP-Server. |
$mode | Übertragungsmodus: FTP_BINARY (seit PHP 7.3 der Standard) für alle Nicht-Textdateien oder FTP_ASCII für reinen Text, dessen Zeilenenden normalisiert werden sollen. |
$offset | Byte-Position im lokalen Stream, ab der das Schreiben beginnen soll — wird verwendet, um einen teilweise abgebrochenen Download fortzusetzen. Standardmäßig 0. |
Die Funktion gibt bei Erfolg true und bei einem Fehler false zurück.
Eine Datei mit ftp_fget() herunterladen
Ein vollständiger Download besteht aus vier Schritten: verbinden, einloggen, ein lokales Handle öffnen und dann abrufen. Schließen Sie sowohl das Handle als auch die Verbindung, wenn Sie fertig sind.
<?php
// 1. Connect (returns false on failure)
$ftp = ftp_connect('ftp.example.com');
if ($ftp === false) {
exit("Could not connect to the FTP server.\n");
}
// 2. Authenticate
if (!ftp_login($ftp, 'username', 'password')) {
exit("FTP login failed.\n");
}
// Most networks need passive mode so the data channel works behind NAT/firewalls
ftp_pasv($ftp, true);
// 3. Open a local handle for writing
$handle = fopen('downloads/report.pdf', 'w');
// 4. Download into that handle (binary mode for a PDF)
if (ftp_fget($ftp, $handle, 'public/report.pdf', FTP_BINARY)) {
echo "Download complete.\n";
} else {
echo "Download failed.\n";
}
fclose($handle);
ftp_close($ftp);Der Aufruf von ftp_pasv() zur Aktivierung des passiven Modus ist fast immer erforderlich, wenn sich der Client hinter einer Firewall oder NAT befindet — was der häufigste Fall ist; ohne ihn kann die Datenübertragung hängen bleiben.
Einen Übertragungsmodus wählen
FTP_BINARYkopiert die Datei Byte für Byte. Verwenden Sie ihn für Bilder, Archive, PDFs, ausführbare Dateien — alles, was kein reiner Text ist. Er ist der sichere Standard.FTP_ASCIIkonvertiert Zeilenenden, damit sie zur Zielplattform passen. Verwenden Sie ihn nur für Textdateien und nur dann, wenn Sie diese Konvertierung tatsächlich wünschen. Das Senden einer Binärdatei im ASCII-Modus korrumpiert sie.
Einen unterbrochenen Download fortsetzen
Der Parameter $offset ermöglicht es Ihnen, einen abgebrochenen Download fortzusetzen. Öffnen Sie die vorhandene Teildatei zum Anhängen, ermitteln Sie, wie viele Bytes Sie bereits haben, und teilen Sie ftp_fget() mit, ab welcher Stelle das Schreiben beginnen soll:
<?php
$local = 'downloads/big.iso';
// Open in append mode so previously downloaded bytes are preserved
$handle = fopen($local, 'a');
// How many bytes we already have locally
$alreadyHave = file_exists($local) ? filesize($local) : 0;
if (ftp_fget($ftp, $handle, 'images/big.iso', FTP_BINARY, $alreadyHave)) {
echo "Resumed and finished the download.\n";
}
fclose($handle);Bei sehr großen Dateien bevorzugen Sie möglicherweise die nicht-blockierende Variante ftp_nb_fget(), die zwischen den Chunks die Kontrolle an Ihr Skript zurückgibt, sodass Sie den Fortschritt anzeigen können.
Fehlerbehandlung
ftp_fget() gibt nur false zurück — es wirft keine Ausnahme — daher sollten Sie den Rückgabewert jedes Schritts prüfen, nicht nur den des Downloads. Der Vergleich mit === verhindert, dass ein falscher, aber gültiger Wert fälschlicherweise behandelt wird.
<?php
$handle = fopen('downloads/data.csv', 'w');
if ($handle === false) {
exit("Could not open the local file for writing.\n");
}
if (ftp_fget($ftp, $handle, 'exports/data.csv', FTP_ASCII) === false) {
// Common causes: wrong remote path, no read permission, or a dropped data channel
echo "Failed to retrieve the file.\n";
} else {
echo "File retrieved successfully.\n";
}
fclose($handle);Häufige Fehler
- Einen Pfad statt eines Handles übergeben. Das zweite Argument muss eine Ressource von
fopen()sein. Wenn Sie einen Pfad haben, verwenden Sie stattdessenftp_get(). - Den passiven Modus vergessen. Hinter einer Firewall kann der Transfer ohne Aufruf von
ftp_pasv()stillschweigend hängen bleiben. - Falscher Übertragungsmodus. Der ASCII-Modus verstümmelt Binärdateien; der Binärmodus hinterlässt nur auf seltenen Plattformen störende Zeilenenden in Textdateien, daher ist Binär der sicherere Standard.
- Ressourcen nicht schließen. Rufen Sie
fclose()undftp_close()auf, damit Puffer geleert und die Verbindung freigegeben wird.
Verwandte Funktionen
ftp_get()— Herunterladen in einen lokalen Pfad (kein Handle erforderlich).ftp_fput()— Das Upload-Gegenstück, das von einem offenen Handle sendet.ftp_nb_fget()— Nicht-blockierender Download in ein Handle.ftp_connect()undftp_login()— Sitzung öffnen und authentifizieren.