W3docs

ftp_mlsd()

Aprenda a função PHP ftp_mlsd(): liste um diretório FTP em formato estruturado e legível por máquina. Sintaxe, valores de retorno, exemplos e tratamento de erros.

O que é ftp_mlsd()?

ftp_mlsd() é uma função PHP embutida (disponível desde o PHP 7.2) que lista o conteúdo de um diretório em um servidor FTP usando o comando FTP MLSD. Ao contrário de funções de listagem mais antigas, ela retorna um resultado estruturado e legível por máquina: em vez de um bloco de texto bruto que você precisa analisar manualmente, você obtém um array de entradas onde cada arquivo ou diretório possui atributos nomeados, como tipo, tamanho e hora de modificação.

Isso é importante porque as listagens de diretórios de servidores FTP são notoriamente inconsistentes — ftp_rawlist() retorna linhas cujo formato depende do sistema operacional do servidor. O MLSD foi adicionado ao protocolo FTP (RFC 3659) justamente para padronizar isso, e ftp_mlsd() o expõe diretamente.

Use ftp_mlsd() quando precisar:

  • Enumerar arquivos e conhecer o tamanho, tipo ou timestamp de cada um.
  • Diferenciar diretórios de arquivos de forma confiável (o atributo type faz isso por você).
  • Evitar a análise frágil de strings que ftp_rawlist() impõe.

Se você precisa apenas de uma lista simples de nomes de arquivos, ftp_nlist() é mais simples. Se for necessário suportar servidores anteriores ao 7.2 ou servidores sem suporte ao MLSD, use ftp_rawlist() como alternativa.

Sintaxe de ftp_mlsd()

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

A função recebe dois parâmetros obrigatórios:

ParâmetroDescrição
$ftpO identificador de conexão FTP retornado por ftp_connect() (ou ftp_ssl_connect()).
$directoryO caminho do diretório a ser listado, por exemplo, /public_html ou . para o diretório atual.
Nota

Ambos os parâmetros são obrigatórios. O comando MLSD sempre opera em um caminho explícito — passe . se quiser o diretório em que você está atualmente.

Ela retorna um array de entradas em caso de sucesso, ou false em caso de falha (por exemplo, se o caminho não existir ou o servidor não suportar MLSD).

O que ftp_mlsd() retorna

Cada elemento do array retornado é um array associativo que descreve uma entrada. As chaves exatas dependem do que o servidor reporta, mas as mais comuns são:

ChaveSignificado
nameO nome do arquivo ou diretório.
typeO tipo da entrada: file, dir, cdir (diretório atual, .) ou pdir (diretório pai, ..).
sizeTamanho em bytes (geralmente presente apenas para arquivos).
modifyTimestamp da última modificação, formatado como YYYYMMDDHHMMSS.
permsString de permissões conforme reportado pelo servidor.
uniqueUm identificador atribuído pelo servidor que é único por arquivo.

A estrutura de uma única entrada se parece com isso:

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

Uso de ftp_mlsd()

Antes de listar qualquer coisa, você se conecta com ftp_connect() e se autentica com ftp_login(). O fluxo completo se parece com este:

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

Iterando sobre a listagem

O valor real de ftp_mlsd() está nos dados estruturados. Aqui imprimimos cada arquivo com um tamanho legível por humanos e ignoramos as pseudo-entradas . e ..:

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

O campo modify é um timestamp de 14 dígitos. Você pode convertê-lo em uma data real com DateTime:

<?php

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

Tratamento de erros em ftp_mlsd()

ftp_mlsd() retorna false em caso de falha, portanto, sempre verifique o resultado antes de iterar sobre ele — chamar foreach em false emitiria um aviso e não processaria 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";
    }
}
Aviso

Use a comparação estrita === false. Um diretório vazio retorna um array vazio [], que é falsy — uma verificação solta if (!$entries) trataria incorretamente um diretório vazio (mas válido) como um erro.

Razões comuns pelas quais ftp_mlsd() falha:

  • O servidor não suporta o comando MLSD (servidores FTP mais antigos ou mínimos). Use ftp_rawlist() como alternativa.
  • O caminho do diretório está errado ou você não tem permissão para lê-lo.
  • Você ainda não está autenticado ou a conexão expirou.

ftp_mlsd() vs. outras funções de listagem

FunçãoRetornaMelhor para
ftp_mlsd()Array estruturado (name, type, size, modify…)Metadados confiáveis entre servidores (PHP 7.2+)
ftp_nlist()Array simples de nomesUma lista rápida apenas de nomes de arquivos
ftp_rawlist()Array de linhas no estilo ls brutoServidores legados sem MLSD

Conclusão

ftp_mlsd() é a forma moderna e confiável de listar um diretório FTP em PHP: ela fornece um array estruturado com o tipo, tamanho e hora de modificação de cada entrada, poupando você da análise frágil de texto que as funções mais antigas exigem. Combine-a com ftp_connect(), ftp_login() e ftp_close() para um fluxo de trabalho de listagem FTP completo e robusto — e lembre-se de verificar === false antes de iterar.

Prática

Prática
Para que serve o comando FTP MLSD no PHP?
Para que serve o comando FTP MLSD no PHP?
Was this page helpful?