W3docs

ftp_fget()

La funzione ftp_fget() è una funzione PHP integrata che scarica un file remoto dal server FTP e lo salva in un file handle locale già aperto.

Cos'è ftp_fget()?

ftp_fget() scarica un file da un server FTP e lo scrive in un file handle locale già aperto. Questa è la differenza fondamentale rispetto a ftp_get(): ftp_get() accetta un percorso locale e crea il file per te, mentre ftp_fget() accetta una risorsa file aperta (il valore restituito da fopen()). Poiché gestisci direttamente l'handle, ftp_fget() è utile quando vuoi scrivere in uno stream che non è un semplice file — uno stream temporaneo (php://temp), un buffer in memoria, o un handle posizionato con fseek().

Questa pagina tratta la firma della funzione, un download funzionante completo, come scegliere la modalità di trasferimento, come riprendere un download interrotto e la gestione degli errori necessaria nel codice reale.

L'estensione FTP procedurale fa ancora parte di PHP. A partire da PHP 8.1 la connessione è un oggetto FTP\Connection anziché una resource, ma il codice che scrivi rimane invariato. Per i trasferimenti cifrati usa ftp_ssl_connect() al posto di ftp_connect().

Sintassi di ftp_fget()

ftp_fget(
    FTP\Connection $ftp,
    resource $stream,
    string $remote_filename,
    int $mode = FTP_BINARY,
    int $offset = 0
): bool
ParametroDescrizione
$ftpLa connessione restituita da ftp_connect() (e autenticata con ftp_login()).
$streamUn puntatore a file locale aperto in cui vengono scritti i dati scaricati. Deve essere aperto in scrittura ('w', 'w+', 'a', ecc.).
$remote_filenamePercorso del file sul server FTP.
$modeModalità di trasferimento: FTP_BINARY (impostazione predefinita da PHP 7.3) per qualsiasi file non testuale, oppure FTP_ASCII per testo normale con normalizzazione dei fine riga.
$offsetPosizione in byte nello stream locale da cui iniziare a scrivere — usata per riprendere un download parziale. Il valore predefinito è 0.

Restituisce true in caso di successo e false in caso di fallimento.

Scaricare un file con ftp_fget()

Un download completo prevede quattro passaggi: connettiti, accedi, apri un handle locale, poi scarica. Chiudi sempre sia l'handle che la connessione al termine.

<?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);

Chiamare ftp_pasv() per abilitare la modalità passiva è quasi sempre necessario quando il client si trova dietro un firewall o NAT, che è il caso più comune; senza di essa il trasferimento dati può bloccarsi.

Scegliere la modalità di trasferimento

  • FTP_BINARY copia il file byte per byte. Usala per immagini, archivi, PDF, eseguibili — qualsiasi file che non sia testo normale. È l'impostazione predefinita sicura.
  • FTP_ASCII converte i fine riga per adattarli alla piattaforma di destinazione. Usala solo per i file di testo e solo quando vuoi effettivamente tale conversione. Inviare un file binario in modalità ASCII lo corrompe.

Riprendere un download interrotto

Il parametro $offset ti consente di continuare un download che è stato interrotto. Apri il file parziale esistente in modalità append, scopri quanti byte hai già scaricato e indica a ftp_fget() da dove iniziare a scrivere:

<?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);

Per file molto grandi potresti preferire la variante non bloccante ftp_nb_fget(), che restituisce il controllo al tuo script tra un blocco e l'altro così puoi mostrare l'avanzamento.

Gestione degli errori

ftp_fget() restituisce solo false — non genera eccezioni — quindi verifica il valore di ritorno di ogni passaggio, non solo del download. Il confronto con === evita di interpretare erroneamente un valore falsy ma valido.

<?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);

Problemi comuni

  • Passare un percorso invece di un handle. Il secondo argomento deve essere una risorsa restituita da fopen(). Se hai un percorso, usa invece ftp_get().
  • Dimenticare la modalità passiva. Dietro un firewall, omettere ftp_pasv() può causare il blocco silenzioso del trasferimento.
  • Modalità di trasferimento errata. La modalità ASCII danneggia i file binari; la modalità binaria lascia fine riga indesiderati nei file di testo solo su rare piattaforme, quindi il binario è l'impostazione predefinita più sicura.
  • Non chiudere le risorse. Chiama fclose() e ftp_close() affinché i buffer vengano svuotati e la connessione venga rilasciata.

Funzioni correlate

Pratica

Pratica
Qual è la funzionalità della funzione ftp_fget() in PHP?
Qual è la funzionalità della funzione ftp_fget() in PHP?
Was this page helpful?