W3docs

PHP FTP

FTP en PHP permite conectarse a servidores remotos para transferir, listar y gestionar archivos mediante la extensión ext-ftp integrada.

Introducción

FTP (File Transfer Protocol) es un protocolo de red estándar para transferir archivos entre un cliente y un servidor a través de una conexión TCP. PHP incluye una extensión FTP integrada (ext-ftp) que permite a tus scripts iniciar sesión en un servidor remoto y mover archivos de forma programática — útil para desplegar recursos, sincronizar copias de seguridad o extraer feeds de datos desde el servidor de un socio.

Este capítulo cubre el flujo de trabajo completo: conectar, iniciar sesión, cambiar al modo pasivo, subir y descargar archivos, listar y gestionar archivos remotos, y finalmente cerrar la conexión correctamente. También explica las advertencias de seguridad que debes conocer antes de usar FTP simple en producción.

Nota de seguridad primero. El FTP simple envía tu nombre de usuario, contraseña y el contenido de los archivos sin cifrar. Para cualquier dato sensible, usa ftp_ssl_connect() (FTP sobre TLS) o prefiere SFTP (SSH File Transfer Protocol), que la extensión FTP no soporta — usa la extensión PHP SSH2 o una librería como phpseclib para SFTP.

El flujo de trabajo típico de FTP

Todo script FTP sigue la misma estructura, independientemente de la operación que realices:

  1. Conectar al servidor — ftp_connect() (o ftp_ssl_connect() para FTPS).
  2. Autenticarftp_login().
  3. Configurar — generalmente ftp_pasv($conn, true) para habilitar el modo pasivo.
  4. Transferir / gestionar archivos — ftp_put(), ftp_get(), ftp_nlist(), etc.
  5. Cerrarftp_close().

Conectarse a un servidor FTP

Establece una conexión con ftp_connect(). Recibe el nombre de host (y opcionalmente el puerto y el tiempo de espera) y devuelve un objeto FTP\Connection en caso de éxito (un recurso antes de PHP 8.1), o false en caso de error.

<?php

$conn = ftp_connect("ftp.example.com", 21, 10); // host, port, timeout (seconds)
if ($conn === false) {
    die("Could not connect to FTP server");
}
echo "Connected.";

Ten en cuenta que conectarse no inicia sesión — en este punto tienes un canal anónimo y sin autenticar. Aún debes llamar a ftp_login() antes de que el servidor te permita hacer algo útil.

Usar FTPS (FTP sobre TLS)

Para cifrar los canales de control y datos, reemplaza ftp_connect() por ftp_ssl_connect(). El resto de la API es idéntico:

<?php

$conn = ftp_ssl_connect("ftp.example.com");
if ($conn === false) {
    die("Could not open a secure FTP connection");
}

Iniciar sesión y modo pasivo

Después de conectarte, autentícate con ftp_login(). Para servidores públicos que permiten acceso anónimo, usa el nombre de usuario anonymous con una contraseña similar a un correo electrónico.

<?php

$conn = ftp_connect("ftp.example.com");

if (!ftp_login($conn, "username", "password")) {
    ftp_close($conn);
    die("Login failed");
}

// Most networks behind a firewall/NAT require passive mode.
ftp_pasv($conn, true);

echo "Logged in.";

Por qué importa el modo pasivo. En el modo activo, el servidor abre una conexión de datos de vuelta a tu cliente, lo que los firewalls y routers NAT casi siempre bloquean. En el modo pasivo, el cliente abre la conexión de datos al servidor, por lo que funciona detrás de firewalls. Como regla general, llama a ftp_pasv($conn, true) justo después de iniciar sesión. Debe establecerse después de ftp_login(), no antes.

Subir archivos

Usa ftp_put() para enviar un archivo local al servidor. Su firma es ftp_put($conn, $remote_file, $local_file, $mode), donde $mode es FTP_BINARY o FTP_ASCII.

<?php

$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);

if (ftp_put($conn, "/public_html/report.pdf", "report.pdf", FTP_BINARY)) {
    echo "Upload successful";
} else {
    echo "Upload failed";
}

ftp_close($conn);

FTP_BINARY vs FTP_ASCII. Usa FTP_BINARY para todo lo que no sea texto plano — imágenes, PDFs, archivos comprimidos, ejecutables — porque el modo ASCII reescribe los finales de línea y corromperá datos binarios. Usa FTP_ASCII solo cuando quieras específicamente que los finales de línea se traduzcan entre plataformas para archivos de texto. En caso de duda, elige FTP_BINARY; es la opción segura por defecto.

Para archivos grandes puedes subir de forma no bloqueante con ftp_nb_put(), lo que permite que tu script realice otras tareas entre fragmentos.

Descargar archivos

ftp_get() recupera un archivo remoto al sistema de archivos local. El orden de los argumentos es ftp_get($conn, $local_file, $remote_file, $mode) — nota que el destino local va primero, lo contrario de ftp_put(). Confundir estos es el error de FTP más común.

<?php

$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);

// local_file first, then remote_file
if (ftp_get($conn, "backup.zip", "/backups/backup.zip", FTP_BINARY)) {
    echo "Download successful";
} else {
    echo "Download failed";
}

ftp_close($conn);

Listar y gestionar archivos remotos

La extensión FTP hace mucho más que transferir archivos. Las funciones de gestión más comunes incluyen:

FunciónPropósito
ftp_nlist($conn, $dir)Array con los nombres de archivos en un directorio
ftp_rawlist($conn, $dir)Listado detallado al estilo ls -l
ftp_size($conn, $file)Tamaño del archivo en bytes (-1 en caso de error)
ftp_mkdir($conn, $dir)Crear un directorio
ftp_rmdir($conn, $dir)Eliminar un directorio (vacío)
ftp_delete($conn, $file)Eliminar un archivo
ftp_rename($conn, $from, $to)Renombrar / mover un archivo
ftp_chdir($conn, $dir)Cambiar el directorio de trabajo
ftp_pwd($conn)Directorio de trabajo actual
ftp_chmod($conn, 0644, $file)Cambiar permisos del archivo
<?php

$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);

$files = ftp_nlist($conn, "/public_html");
foreach ($files as $file) {
    echo $file, " — ", ftp_size($conn, $file), " bytes\n";
}

ftp_close($conn);

Cerrar la conexión

Siempre libera la conexión con ftp_close() cuando hayas terminado. Envolver el flujo de trabajo en try/finally garantiza que el socket se cierre incluso si se lanza un error a mitad del proceso:

<?php

$conn = ftp_connect("ftp.example.com");
if (!$conn || !ftp_login($conn, "username", "password")) {
    die("Connection or login failed");
}

try {
    ftp_pasv($conn, true);
    ftp_put($conn, "/public_html/index.html", "index.html", FTP_BINARY);
} finally {
    ftp_close($conn);
}

Buenas prácticas y errores comunes

  • Prefiere FTPS o SFTP. Nunca envíes credenciales por FTP simple a través de internet público.
  • Siempre habilita el modo pasivo (ftp_pasv) a menos que tengas una razón específica para no hacerlo.
  • Elige el modo de transferencia correctoFTP_BINARY para datos binarios, FTP_ASCII solo para texto donde se desee traducir los finales de línea.
  • Presta atención al orden de los argumentosftp_put es (remote, local), ftp_get es (local, remote).
  • Siempre cierra la conexión con ftp_close().
  • Comprueba cada valor de retorno. Las funciones FTP devuelven false en caso de error en lugar de lanzar excepciones, por lo que es fácil pasar por alto fallos silenciosos.
  • ext-ftp debe estar habilitado. Confirma con extension_loaded('ftp'); si devuelve false, habilita la extensión en tu php.ini.

Temas relacionados

Práctica

Práctica
¿Cuáles son las funciones de FTP en PHP?
¿Cuáles son las funciones de FTP en PHP?
Was this page helpful?