scandir()
Aprenda a usar a função scandir() do PHP para ler o conteúdo de diretórios, ordenar resultados e tratar erros com segurança.
Introdução
O tratamento de diretórios é uma parte essencial da programação em PHP — quase todo script de backup, upload de arquivos ou processador de recursos precisa listar o conteúdo de uma pasta. Este artigo aprofunda a função scandir() do PHP, que lê o conteúdo de um diretório em uma única chamada. Você aprenderá o que ela retorna, como ordenar e filtrar o resultado, como ela difere de glob() e como tratar erros com segurança.
O que é scandir?
scandir() lê um diretório e retorna os nomes de todas as entradas que ele contém — arquivos e subdiretórios — como um array plano de strings. O array sempre inclui as duas entradas especiais . (o diretório atual) e .. (o diretório pai), então você quase sempre as filtra antes de usar o resultado.
Se o diretório não puder ser lido, scandir() retorna false e emite um aviso. A função está disponível desde o PHP 4.3.0 e funciona tanto em sistemas Unix quanto no Windows.
Sintaxe
scandir(string $directory, int $sorting_order = SCANDIR_SORT_ASCENDING, ?resource $context = null): array|false| Parâmetro | Descrição |
|---|---|
$directory | Caminho para o diretório que você deseja ler. Pode ser absoluto ou relativo ao diretório de trabalho do script. |
$sorting_order | Como o resultado é ordenado: SCANDIR_SORT_ASCENDING (padrão, A→Z), SCANDIR_SORT_DESCENDING (Z→A) ou SCANDIR_SORT_NONE (ordem do sistema de arquivos — mais rápido, sem ordenação). |
$context | Um recurso de contexto de stream opcional (raramente necessário; usado para wrappers de stream personalizados). |
A função retorna um array de nomes de arquivos em caso de sucesso ou false em caso de falha.
Os nomes são retornados sem o caminho do diretório. Para obter um caminho utilizável, adicione o diretório manualmente:
$directory . '/' . $entry.
Como funciona o scandir?
Na forma mais simples, você passa apenas o caminho do diretório. O conteúdo é retornado ordenado alfabeticamente (crescente), pois esse é o $sorting_order padrão. O exemplo abaixo filtra . e .. com array_diff() para que apenas entradas reais permaneçam:
Exemplo da função scandir() em PHP
<?php
$dir = "/path/to/directory";
$files = scandir($dir);
// Filter out the current and parent directory entries
$filtered = array_diff($files, ['.', '..']);
foreach ($filtered as $file) {
echo $file . "<br>";
}Este código exibe uma lista de arquivos e subdiretórios no diretório especificado, excluindo . e ...
Ordenando o conteúdo do diretório
Passe um segundo argumento para controlar a ordem do resultado. As três opções são:
SCANDIR_SORT_ASCENDING— alfabética A→Z (o padrão).SCANDIR_SORT_DESCENDING— alfabética Z→A.SCANDIR_SORT_NONE— sem ordenação; as entradas são retornadas na ordem em que o sistema de arquivos as fornece. Esta é a opção mais rápida e vale a pena usar quando você vai ordenar a lista por conta própria, ou quando a ordem não importa.
Por exemplo, dado um diretório contendo archive.txt, data.csv, report.txt, notes.md, image.png e um subdiretório backups:
Como ordenar a saída do scandir() em ordem decrescente
<?php
$dir = "/path/to/directory";
$files = scandir($dir, SCANDIR_SORT_DESCENDING);
print_r($files);
// Array
// (
// [0] => report.txt
// [1] => notes.md
// [2] => image.png
// [3] => data.csv
// [4] => backups
// [5] => ..
// [6] => .
// )Os mesmos dados com SCANDIR_SORT_NONE são retornados sem ordenação (a ordem exata depende do sistema de arquivos), o que evita o pequeno custo de ordenação.
Listando apenas arquivos (ou apenas diretórios)
scandir() retorna arquivos e pastas misturados. Para manter apenas arquivos, teste cada entrada com is_file(); para manter apenas diretórios, use is_dir(). Lembre-se de construir o caminho completo primeiro:
<?php
$dir = "/path/to/directory";
$entries = array_diff(scandir($dir), ['.', '..']);
$filesOnly = array_filter($entries, fn($entry) => is_file($dir . '/' . $entry));
print_r(array_values($filesOnly));
// Array
// (
// [0] => archive.txt
// [1] => data.csv
// [2] => image.png
// [3] => notes.md
// [4] => report.txt
// )Filtrando por extensão de arquivo
Uma tarefa comum é obter apenas arquivos de um determinado tipo. Combine scandir() com pathinfo() para ler a extensão de cada entrada:
<?php
$dir = "/path/to/directory";
$entries = array_diff(scandir($dir), ['.', '..']);
$textFiles = array_filter(
$entries,
fn($entry) => pathinfo($entry, PATHINFO_EXTENSION) === 'txt'
);
print_r(array_values($textFiles));
// Array
// (
// [0] => archive.txt
// [1] => report.txt
// )Se você só precisa corresponder arquivos por um padrão, glob() pode fazer isso em uma etapa — por exemplo glob("$dir/*.txt") — e retorna caminhos completos. Use glob() para correspondência de padrões e scandir() quando quiser todas as entradas e controle total sobre a filtragem.
Tratamento de erros
A função scandir pode falhar se o caminho do diretório especificado for inválido ou se o diretório não tiver as permissões adequadas. Em caso de falha, ela retorna false e dispara um aviso. Ela não lança exceções, então você deve verificar o valor de retorno diretamente. Veja um exemplo:
Exemplo da função scandir() em PHP com tratamento de erros
<?php
$dir = "/path/to/directory";
$files = scandir($dir);
if ($files === false) {
echo "Error: Could not read the directory.";
} else {
foreach ($files as $file) {
echo $file . "<br>";
}
}Este código verifica o valor de retorno de scandir() e exibe uma mensagem de erro se o diretório não puder ser lido. Como scandir() emite um aviso (não uma exceção) quando falha, a verificação estrita === false é o que realmente protege seu código — e silenciar o aviso com @scandir() é desencorajado, pois você perde a mensagem de diagnóstico.
Para evitar o aviso completamente, confirme que o caminho é um diretório legível antes de chamar scandir():
<?php
$dir = "/path/to/directory";
if (is_dir($dir)) {
$files = scandir($dir);
foreach (array_diff($files, ['.', '..']) as $file) {
echo $file . "<br>";
}
} else {
echo "Error: '$dir' is not a valid directory.";
}scandir() vs outras funções de diretório
| Função | Retorna | Melhor para |
|---|---|---|
scandir() | Um array com todos os nomes de entradas de uma vez | Obter a listagem completa em uma linha e depois filtrar/ordenar |
glob() | Caminhos completos que correspondem a um padrão | Correspondência de padrões como *.jpg |
opendir() + readdir() | Um handle de diretório que você lê entrada por entrada | Diretórios muito grandes onde você não quer a lista inteira na memória |
Para uma visão geral do conjunto de ferramentas mais amplo, veja Trabalhando com diretórios em PHP.
Conclusão
A função scandir() é uma maneira conveniente e de uma única chamada para ler o conteúdo de um diretório em PHP. Você viu como listar entradas, ordená-las com as três constantes SCANDIR_SORT_*, manter apenas arquivos ou apenas diretórios, filtrar por extensão e tratar falhas com segurança. Use scandir() quando quiser a listagem completa e controle total; use glob() quando uma simples correspondência de padrão for suficiente.