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
typefaz 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|falseA função recebe dois parâmetros obrigatórios:
| Parâmetro | Descrição |
|---|---|
$ftp | O identificador de conexão FTP retornado por ftp_connect() (ou ftp_ssl_connect()). |
$directory | O caminho do diretório a ser listado, por exemplo, /public_html ou . para o diretório atual. |
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:
| Chave | Significado |
|---|---|
name | O nome do arquivo ou diretório. |
type | O tipo da entrada: file, dir, cdir (diretório atual, .) ou pdir (diretório pai, ..). |
size | Tamanho em bytes (geralmente presente apenas para arquivos). |
modify | Timestamp da última modificação, formatado como YYYYMMDDHHMMSS. |
perms | String de permissões conforme reportado pelo servidor. |
unique | Um 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";
}
}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). Useftp_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ção | Retorna | Melhor para |
|---|---|---|
ftp_mlsd() | Array estruturado (name, type, size, modify…) | Metadados confiáveis entre servidores (PHP 7.2+) |
ftp_nlist() | Array simples de nomes | Uma lista rápida apenas de nomes de arquivos |
ftp_rawlist() | Array de linhas no estilo ls bruto | Servidores 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.