W3docs

ftp_pasv()

La función ftp_pasv() de PHP activa o desactiva el modo pasivo en una conexión FTP. Aprende su sintaxis, cuándo usarla y ejemplos prácticos.

La función ftp_pasv() de PHP

La función ftp_pasv() activa o desactiva el modo pasivo en una conexión FTP abierta. El modo pasivo controla qué lado abre el canal de datos durante una transferencia, y configurarlo correctamente es la solución más habitual cuando las descargas FTP o los listados de directorios se bloquean o agotan el tiempo de espera. Este capítulo explica qué es el modo pasivo, cuándo es necesario y cómo llamar a ftp_pasv() correctamente en un script de transferencia real.

Modo activo vs. modo pasivo

FTP utiliza dos canales separados: un canal de comandos (donde se envían LIST, RETR, etc.) y un canal de datos (por donde fluyen los bytes del archivo o el listado). Los dos modos difieren únicamente en quién abre el canal de datos:

  • Modo activo (predeterminado en el protocolo): el servidor abre la conexión de datos de vuelta al cliente. Si el cliente está detrás de un firewall o un router NAT, esa conexión entrante suele estar bloqueada, por lo que la transferencia se detiene.
  • Modo pasivo: el cliente abre ambos canales hacia el servidor. Como el cliente solo realiza conexiones salientes, funciona a través de casi cualquier firewall o configuración NAT.

Por eso el modo pasivo es el predeterminado seguro para la mayoría de los scripts modernos: los clientes casi siempre están detrás de NAT, mientras que los servidores son accesibles desde una dirección pública.

Sintaxis

ftp_pasv(FTP\Connection $ftp, bool $passive): bool
  • $ftp — la conexión FTP devuelta por ftp_connect(). A partir de PHP 8.1 es un objeto FTP\Connection; en PHP 8.0 y versiones anteriores era un resource. El código existente sigue funcionando de cualquier manera.
  • $passivetrue para activar el modo pasivo, false para volver al modo activo.

La función devuelve true en caso de éxito y false en caso de error.

El orden importa: llama a ftp_pasv() después de ftp_login() y antes de cualquier transferencia como ftp_get(), ftp_put() o ftp_nlist(). Llamarla antes de iniciar sesión falla porque el modo pasivo se negocia dentro de una sesión autenticada.

Una transferencia completa en modo pasivo

El siguiente ejemplo se conecta, inicia sesión, cambia al modo pasivo, descarga un archivo y limpia los recursos. Cada paso comprueba su valor de retorno para que los errores se reporten en lugar de ignorarse silenciosamente.

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

Sin la línea ftp_pasv($ftp, true), el paso 4 se bloquearía con frecuencia detrás de un router NAT porque el servidor no podría abrir la conexión de datos entrante.

Manejo de errores

ftp_pasv() devuelve false cuando el servidor rechaza el cambio de modo o la conexión ya no es válida. Comprueba siempre el valor de retorno antes de intentar una transferencia y usa ftp_close() para liberar la conexión en cada ruta de salida:

<?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
}

Cuándo usar el modo activo en su lugar

El modo pasivo es adecuado para la mayoría de los clientes, pero hay situaciones que requieren el modo activo (ftp_pasv($ftp, false)):

  • El rango de puertos pasivos del servidor está bloqueado por firewall, por lo que las conexiones de datos pasivas son rechazadas mientras las activas tienen éxito.
  • Te conectas desde un host con IP pública y sin restricciones de entrada, hablando con un servidor que solo permite transferencias activas.

Si una transferencia se bloquea, cambiar el modo es lo primero que hay que probar: muchos informes de "FTP no funciona" son simplemente el modo incorrecto para la red.

Conclusión

ftp_pasv() decide si el cliente o el servidor abre el canal de datos FTP. Actívalo (true) para clientes detrás de firewalls o NAT — que es la mayoría de las veces — y llámalo justo después de ftp_login() y antes de cualquier transferencia. Comprobar su valor de retorno y cerrar la conexión con ftp_close() mantiene tus scripts FTP fiables en diferentes configuraciones de red.

Práctica

Práctica
What does the pasv() function do in FTP using PHP?
What does the pasv() function do in FTP using PHP?
Was this page helpful?