readdir()
A função readdir() do PHP lê entradas de um diretório aberto com opendir(), retornando um nome por chamada até esgotar as entradas.
A função PHP readdir() lê uma entrada por vez de um diretório que você já abriu com opendir(). Cada chamada retorna o nome do próximo arquivo ou subdiretório e avança um ponteiro interno, de modo que chamá-la em um loop permite percorrer todos os itens de uma pasta. Esta página explica a sintaxe, o valor de retorno, o padrão de loop que evita um erro comum e como readdir() se compara a alternativas de nível mais alto.
Sintaxe
readdir(resource $dir_handle = null): string|false$dir_handle— um identificador de diretório retornado poropendir(). Se omitido, o PHP usa o último identificador aberto poropendir().- Valor de retorno — o nome do arquivo da próxima entrada como string, ou
falsequando não houver mais entradas. As entradas incluem os nomes especiais.(diretório atual) e..(diretório pai), e são retornadas na ordem em que o sistema de arquivos as armazena, não em ordem alfabética.
Lendo um diretório
Para usar readdir(), primeiro abra um identificador de diretório com opendir(), faça um loop com readdir() até que ele retorne false, depois libere o identificador com closedir():
<?php
$dir = __DIR__; // the directory this script lives in
if ($handle = opendir($dir)) {
while (false !== ($entry = readdir($handle))) {
if ($entry !== "." && $entry !== "..") {
echo "$entry\n";
}
}
closedir($handle);
}Isso abre o diretório, itera pelo seu conteúdo e imprime cada nome exceto . e ... A chamada closedir() libera o identificador quando você terminar.
Por que false !== e não apenas uma verificação de verdade
A comparação estrita false !== ($entry = readdir($handle)) é essencial, não apenas estilística. Um diretório pode legitimamente conter uma entrada chamada "0", e uma verificação de string vazia também se comportaria mal. O PHP trata a string "0" como falsa, portanto escrever while ($entry = readdir($handle)) interromperia o loop prematuramente ao encontrar tal arquivo. Comparar estritamente com false faz com que o loop termine apenas quando readdir() realmente esgota as entradas.
Filtrando entradas por extensão
readdir() retorna nomes brutos, então qualquer filtragem fica por sua conta. Combine-o com pathinfo() para manter apenas os tipos de arquivo que você deseja — neste caso, imagens:
<?php
$dir = __DIR__;
$allowed = ['jpg', 'jpeg', 'png', 'gif'];
if ($handle = opendir($dir)) {
while (false !== ($entry = readdir($handle))) {
$extension = strtolower(pathinfo($entry, PATHINFO_EXTENSION));
if ($entry !== "." && $entry !== ".." && in_array($extension, $allowed, true)) {
echo "$entry\n";
}
}
closedir($handle);
}pathinfo($entry, PATHINFO_EXTENSION) extrai a extensão de cada nome, e in_array(..., true) (modo estrito) a verifica contra a lista de permissões para que apenas os arquivos correspondentes sejam impressos.
Relendo o mesmo diretório
Como cada chamada a readdir() avança o ponteiro interno, um segundo loop sobre o mesmo identificador não retorna nada — o ponteiro já está no final. Use rewinddir() para redefini-lo para a primeira entrada sem reabrir o diretório:
<?php
$handle = opendir(__DIR__);
while (false !== ($entry = readdir($handle))) { /* first pass */ }
rewinddir($handle); // back to the start
while (false !== ($entry = readdir($handle))) {
// second pass sees every entry again
}
closedir($handle);readdir() vs scandir() vs glob()
readdir() é o bloco de construção de baixo nível. Na maioria do código moderno, você recorre a uma alternativa de chamada única:
scandir()retorna todas as entradas como um array ordenado em uma única chamada — sem a necessidade de gerenciaropendir/closedir.glob()corresponde a um padrão no estilo shell (por exemplo*.png) e retorna caminhos completos, tornando a filtragem por extensão uma questão de uma linha.
Recorra a readdir() quando quiser processar entradas uma por vez sem carregar toda a listagem na memória (útil para diretórios muito grandes), ou quando precisar de controle detalhado sobre a iteração.
Erros comuns
- Sempre ignore
.e..—readdir()os inclui, e esquecer de filtrá-los é o erro mais frequente, especialmente em percursos recursivos de diretório. opendir()pode falhar. Se o caminho não existir ou não for legível, ele retornafalsee emite um aviso, razão pela qual os exemplos protegem o loop comif ($handle = opendir($dir)).- Feche seus identificadores. Chame
closedir()(ou deixe o script terminar) para liberar o recurso. - A ordem não é garantida. Se você precisar de saída ordenada, use
scandir()ou ordene os nomes você mesmo.