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 daftp_connect(). A partire da PHP 8.1 è un oggettoFTP\Connection; in PHP 8.0 e versioni precedenti era una resource. Il codice esistente continua a funzionare in entrambi i casi.$passive—trueper abilitare la modalità passiva,falseper tornare alla modalità attiva.
La funzione restituisce true in caso di successo e false in caso di errore.
L'ordine è importante: chiamare
ftp_pasv()dopoftp_login()e prima di qualsiasi trasferimento comeftp_get(),ftp_put()oftp_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.