W3docs

ftp_mlsd()

Aprende la función PHP ftp_mlsd(): lista un directorio FTP en formato estructurado y legible por máquinas. Sintaxis, valores de retorno, ejemplos y manejo de errores.

¿Qué es ftp_mlsd()?

ftp_mlsd() es una función nativa de PHP (disponible desde PHP 7.2) que lista el contenido de un directorio en un servidor FTP usando el comando FTP MLSD. A diferencia de las funciones de listado más antiguas, devuelve un resultado estructurado y legible por máquinas: en lugar de un bloque de texto sin procesar que hay que parsear manualmente, obtienes un array de entradas donde cada archivo o directorio lleva atributos con nombre, como su tipo, tamaño y fecha de modificación.

Esto es importante porque los listados de directorios de los servidores FTP son notoriamente inconsistentes: ftp_rawlist() devuelve líneas cuyo formato depende del sistema operativo del servidor. MLSD se añadió al protocolo FTP (RFC 3659) precisamente para estandarizar esto, y ftp_mlsd() lo expone directamente.

Usa ftp_mlsd() cuando necesites:

  • Enumerar archivos y conocer el tamaño, tipo o marca de tiempo de cada uno.
  • Distinguir de forma fiable los directorios de los archivos (el atributo type hace esto por ti).
  • Evitar el frágil parsing de cadenas que ftp_rawlist() te obliga a realizar.

Si solo necesitas una lista plana de nombres de archivos, ftp_nlist() es más sencillo. Si debes soportar servidores anteriores a la versión 7.2 o servidores sin soporte MLSD, recurre a ftp_rawlist().

Sintaxis de ftp_mlsd()

ftp_mlsd(FTP\Connection $ftp, string $directory): array|false

La función acepta dos parámetros obligatorios:

ParámetroDescripción
$ftpEl identificador de conexión FTP devuelto por ftp_connect() (o ftp_ssl_connect()).
$directoryLa ruta del directorio a listar, p. ej. /public_html o . para el directorio actual.
Nota

Ambos parámetros son obligatorios. El comando MLSD siempre opera sobre una ruta explícita: pasa . si deseas listar el directorio en el que te encuentras actualmente.

Devuelve un array de entradas en caso de éxito, o false en caso de error (por ejemplo, si la ruta no existe o el servidor no soporta MLSD).

Qué devuelve ftp_mlsd()

Cada elemento del array devuelto es un array asociativo que describe una entrada. Las claves exactas dependen de lo que reporte el servidor, pero las más comunes son:

ClaveSignificado
nameEl nombre del archivo o directorio.
typeEl tipo de entrada: file, dir, cdir (directorio actual, .) o pdir (directorio padre, ..).
sizeTamaño en bytes (generalmente presente solo para archivos).
modifyMarca de tiempo de última modificación, con formato YYYYMMDDHHMMSS.
permsCadena de permisos tal como la reporta el servidor.
uniqueUn identificador asignado por el servidor que es único por archivo.

La estructura de una entrada individual tiene este aspecto:

[
    'name'   => 'report.pdf',
    'type'   => 'file',
    'size'   => '20480',
    'modify' => '20240115093000', // 2024-01-15 09:30:00
    'perms'  => 'adfr',
]

Uso de ftp_mlsd()

Antes de listar nada, te conectas con ftp_connect() y te autenticas con ftp_login(). El flujo completo tiene este aspecto:

<?php

// 1. Open a connection
$ftp = ftp_connect('ftp.example.com');

// 2. Authenticate
ftp_login($ftp, 'username', 'password');

// 3. Switch to passive mode (recommended behind firewalls/NAT)
ftp_pasv($ftp, true);

// 4. Get a structured listing of the directory
$entries = ftp_mlsd($ftp, '/public_html');

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

Iterar sobre el listado

El verdadero valor de ftp_mlsd() son los datos estructurados. Aquí imprimimos cada archivo con un tamaño legible por humanos y omitimos las pseudo-entradas . y ..:

<?php

$entries = ftp_mlsd($ftp, '.');

foreach ($entries as $entry) {
    // Skip the current-dir and parent-dir markers
    if (in_array($entry['type'], ['cdir', 'pdir'], true)) {
        continue;
    }

    if ($entry['type'] === 'dir') {
        echo "[DIR]  {$entry['name']}\n";
    } else {
        $kb = round($entry['size'] / 1024, 1);
        echo "[FILE] {$entry['name']} ({$kb} KB)\n";
    }
}

El campo modify es una marca de tiempo de 14 dígitos. Puedes convertirla en una fecha real con DateTime:

<?php

$modified = DateTime::createFromFormat('YmdHis', $entry['modify']);
echo $modified->format('Y-m-d H:i:s');

Manejo de errores en ftp_mlsd()

ftp_mlsd() devuelve false en caso de error, así que comprueba siempre el resultado antes de iterar sobre él: llamar a foreach sobre false emitiría una advertencia y no procesaría nada.

<?php

$entries = ftp_mlsd($ftp, '/path/that/may/not/exist');

if ($entries === false) {
    echo "Failed to retrieve the directory listing.\n";
} else {
    foreach ($entries as $entry) {
        echo $entry['name'] . "\n";
    }
}
Advertencia

Usa la comparación estricta === false. Un directorio vacío devuelve un array vacío [], que es falsy: una comprobación laxa con if (!$entries) trataría erróneamente un directorio vacío (pero válido) como un error.

Razones habituales por las que ftp_mlsd() falla:

  • El servidor no soporta el comando MLSD (servidores FTP antiguos o con funcionalidad mínima). Recurre a ftp_rawlist().
  • La ruta del directorio es incorrecta o no tienes permisos para leerla.
  • Aún no has iniciado sesión, o la conexión ha caducado.

ftp_mlsd() frente a otras funciones de listado

FunciónDevuelveIdeal para
ftp_mlsd()array estructurado (name, type, size, modify…)Metadatos fiables entre servidores (PHP 7.2+)
ftp_nlist()array plano de nombresUna lista rápida solo de nombres de archivos
ftp_rawlist()array de líneas estilo ls sin procesarServidores heredados sin MLSD

Conclusión

ftp_mlsd() es la forma moderna y fiable de listar un directorio FTP en PHP: te entrega un array estructurado con el tipo, tamaño y fecha de modificación de cada entrada, ahorrándote el frágil parsing de texto que requieren las funciones más antiguas. Combínala con ftp_connect(), ftp_login() y ftp_close() para obtener un flujo de trabajo de listado FTP completo y robusto, y recuerda comprobar === false antes de iterar.

Práctica

Práctica
¿Para qué se usa el comando FTP MLSD en PHP?
¿Para qué se usa el comando FTP MLSD en PHP?
Was this page helpful?