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
typehace 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|falseLa función acepta dos parámetros obligatorios:
| Parámetro | Descripción |
|---|---|
$ftp | El identificador de conexión FTP devuelto por ftp_connect() (o ftp_ssl_connect()). |
$directory | La ruta del directorio a listar, p. ej. /public_html o . para el directorio actual. |
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:
| Clave | Significado |
|---|---|
name | El nombre del archivo o directorio. |
type | El tipo de entrada: file, dir, cdir (directorio actual, .) o pdir (directorio padre, ..). |
size | Tamaño en bytes (generalmente presente solo para archivos). |
modify | Marca de tiempo de última modificación, con formato YYYYMMDDHHMMSS. |
perms | Cadena de permisos tal como la reporta el servidor. |
unique | Un 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";
}
}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 aftp_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ón | Devuelve | Ideal para |
|---|---|---|
ftp_mlsd() | array estructurado (name, type, size, modify…) | Metadatos fiables entre servidores (PHP 7.2+) |
ftp_nlist() | array plano de nombres | Una lista rápida solo de nombres de archivos |
ftp_rawlist() | array de líneas estilo ls sin procesar | Servidores 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.