W3docs

ftp_pasv()

La funzione ftp_pasv() di PHP abilita la modalità passiva per la connessione FTP. In questo articolo la esaminiamo in dettaglio.

La funzione PHP ftp_pasv()

La funzione ftp_pasv() attiva o disattiva la modalità passiva per una connessione FTP aperta. La modalità passiva controlla quale lato apre il canale dati durante un trasferimento, e configurarla correttamente è la soluzione più comune quando i download FTP e i listing delle directory si bloccano o vanno in timeout. Questo capitolo spiega cos'è la modalità passiva, quando è necessaria e come chiamare ftp_pasv() correttamente in uno script di trasferimento reale.

Modalità attiva vs. modalità passiva

FTP utilizza due canali separati: un canale di comando (dove si inviano LIST, RETR, ecc.) e un canale dati (dove scorrono i byte del file o del listing). Le due modalità differiscono solo per chi apre il canale dati:

  • Modalità attiva (predefinita nel protocollo): il server apre la connessione dati verso il client. Se il client si trova dietro un firewall o un router NAT, quella connessione in ingresso viene solitamente bloccata, quindi il trasferimento si blocca.
  • Modalità passiva: il client apre entrambi i canali verso il server. Poiché il client effettua solo connessioni in uscita, funziona con quasi qualsiasi configurazione di firewall o NAT.

Ecco perché la modalità passiva è il default sicuro per la maggior parte degli script moderni: i client sono quasi sempre dietro NAT, mentre i server sono raggiungibili su un indirizzo pubblico.

Sintassi

ftp_pasv(FTP\Connection $ftp, bool $passive): bool
  • $ftp — la connessione FTP restituita da ftp_connect(). A partire da PHP 8.1 è un oggetto FTP\Connection; in PHP 8.0 e versioni precedenti era una resource. Il codice esistente continua a funzionare in entrambi i casi.
  • $passivetrue per abilitare la modalità passiva, false per tornare alla modalità attiva.

La funzione restituisce true in caso di successo e false in caso di errore.

L'ordine è importante: chiamare ftp_pasv() dopo ftp_login() e prima di qualsiasi trasferimento come ftp_get(), ftp_put() o ftp_nlist(). Chiamarla prima del login fallisce perché la modalità passiva viene negoziata all'interno di una sessione autenticata.

Un trasferimento completo in modalità passiva

L'esempio seguente si connette, effettua il login, passa alla modalità passiva, scarica un file e chiude la connessione. Ogni passaggio controlla il valore restituito così i fallimenti vengono segnalati invece di essere ignorati silenziosamente.

<?php

// 1. Connect to the FTP server (30-second timeout)
$ftp = ftp_connect('ftp.example.com', 21, 30);
if (!$ftp) {
    die("Could not connect to the FTP server.\n");
}

// 2. Authenticate
if (!ftp_login($ftp, 'username', 'password')) {
    ftp_close($ftp);
    die("FTP login failed.\n");
}

// 3. Switch to passive mode — must come after login, before any transfer
if (!ftp_pasv($ftp, true)) {
    ftp_close($ftp);
    die("Could not switch to passive mode.\n");
}

// 4. Download a file now that the data channel will be client-initiated
if (ftp_get($ftp, 'local-copy.txt', 'remote/report.txt', FTP_BINARY)) {
    echo "File downloaded successfully.\n";
} else {
    echo "File download failed.\n";
}

// 5. Always close the connection
ftp_close($ftp);

Senza la riga ftp_pasv($ftp, true), il passaggio 4 si bloccherebbe spesso dietro un router NAT perché il server non riuscirebbe ad aprire la connessione dati in ingresso.

Gestione degli errori

ftp_pasv() restituisce false quando il server rifiuta il cambio di modalità o la connessione non è più valida. Verificare sempre il valore restituito prima di tentare un trasferimento e usare ftp_close() per rilasciare la connessione su ogni percorso di uscita:

<?php

if (!ftp_pasv($ftp, true)) {
    echo "Failed to enable passive mode on the remote server.\n";
    ftp_close($ftp);
    return; // stop before attempting a transfer that would stall
}

Quando usare la modalità attiva

La modalità passiva si adatta alla maggior parte dei client, ma alcune situazioni richiedono la modalità attiva (ftp_pasv($ftp, false)):

  • L'intervallo di porte passive del server è bloccato dal firewall, quindi le connessioni dati passive vengono rifiutate mentre quelle attive hanno successo.
  • Si effettua la connessione da un host con un IP pubblico e senza restrizioni in ingresso, verso un server che consente solo trasferimenti attivi.

Se un trasferimento si blocca, cambiare modalità è la prima cosa da provare — molte segnalazioni di "FTP non funziona" sono semplicemente la modalità sbagliata per la rete.

Conclusione

ftp_pasv() decide se il client o il server apre il canale dati FTP. Abilitarla (true) per i client dietro firewall o NAT — che è la situazione più comune — e chiamarla subito dopo ftp_login() e prima di qualsiasi trasferimento. Verificare il valore restituito e chiudere la connessione con ftp_close() mantiene gli script FTP affidabili su diverse configurazioni di rete.

Pratica

Pratica
Cosa fa la funzione pasv() in FTP con PHP?
Cosa fa la funzione pasv() in FTP con PHP?
Was this page helpful?