dir()
Saiba como trabalhar com diretórios em PHP: abrir, ler, criar e excluir, além da função dir() e seus substitutos modernos.
Introdução
Este capítulo aborda como trabalhar com diretórios em PHP: abrir, ler, criar e excluí-los, além da função dir() — que foi removida — e seus substitutos modernos. PHP inclui um conjunto completo de funções embutidas para essas tarefas, permitindo listar o conteúdo de uma pasta, percorrer uma árvore de diretórios ou limpar arquivos sem precisar executar comandos do sistema operacional.
Você precisará de funções de diretório com mais frequência ao criar um gerenciador de uploads, gerar uma listagem de arquivos para uma página de downloads, limpar arquivos temporários ou escanear uma pasta de templates ou imagens em tempo de execução.
Entendendo as Funções de Diretório em PHP
PHP agrupa as operações com diretórios em um conjunto de funções procedurais, além de uma classe orientada a objetos chamada DirectoryIterator. As mais comuns são:
opendir()— abre um diretório e retorna um identificador (um recurso que você lê)readdir()— lê a próxima entrada de um identificador de diretório abertoclosedir()— fecha um identificador de diretório e libera o recursoscandir()— lê todas as entradas em um array em uma única chamadaglob()— retorna caminhos que correspondem a um padrão curinga de shellmkdir()— cria um novo diretóriormdir()— exclui um diretório vaziois_dir()— verifica se um caminho é um diretório
Toda listagem de diretório em PHP inclui as entradas especiais . (o próprio diretório) e .. (seu pai). Você quase sempre vai querer ignorá-las — esquecer de fazer isso é uma fonte comum de bugs.
Usando opendir() e readdir() para Ler um Diretório
opendir() abre um diretório e retorna um identificador de diretório. Você então passa esse identificador para readdir(), que retorna o nome da próxima entrada a cada chamada, e false quando não há mais entradas. Sempre feche o identificador com closedir() ao terminar.
Como readdir() pode legitimamente retornar "0" (um arquivo literalmente chamado 0), compare seu resultado com !== false em vez de uma verificação solta, para que um nome de arquivo falso não seja confundido com o fim da lista.
Exemplo de opendir() e readdir() em PHP
<?php
$dir = "/path/to/directory";
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if ($file === "." || $file === "..") {
continue; // skip self and parent
}
echo "filename: " . $file . PHP_EOL;
}
closedir($dh);
}
}Para um diretório contendo a.txt, b.log e report.csv, isso imprime:
filename: b.log
filename: report.csv
filename: a.txtA ordem não é alfabética — readdir() retorna as entradas na ordem em que o sistema de arquivos as armazena. Se você precisar de uma ordem previsível, use scandir() (que ordena) ou classifique os resultados por conta própria.
Usando scandir() para Listar um Diretório de Uma Vez
scandir() lê todo o conteúdo de um diretório em um array em uma única chamada e — ao contrário de readdir() — ordena o resultado alfabeticamente por padrão. Esta é a forma mais conveniente de obter uma lista ordenada de arquivos. Ela ainda inclui . e .., portanto filtre-os quando quiser apenas arquivos reais.
Usando a Função scandir() em PHP
<?php
$dir = "/path/to/directory";
$files = scandir($dir);
print_r($files);Para um diretório contendo a.txt, b.log e report.csv, a saída é:
Array
(
[0] => .
[1] => ..
[2] => a.txt
[3] => b.log
[4] => report.csv
)Passe SCANDIR_SORT_DESCENDING como terceiro argumento para inverter a ordem, ou SCANDIR_SORT_NONE para ignorar a ordenação (o que é mais rápido para diretórios muito grandes).
Encontrando Arquivos com glob()
Quando você só quer arquivos que correspondam a um padrão — todos os arquivos .txt, ou tudo que começa com report — glob() é a opção mais limpa. Ele aceita um padrão curinga de shell e retorna um array de caminhos correspondentes:
<?php
foreach (glob("/path/to/directory/*.txt") as $file) {
echo $file . PHP_EOL;
}Se apenas a.txt corresponder em nosso diretório de exemplo, isso imprime:
/path/to/directory/a.txtAo contrário de scandir(), glob() não inclui . e .., e retorna caminhos completos em vez de nomes de arquivos simples.
Criando Diretórios com mkdir()
A função mkdir() cria um novo diretório. Seu primeiro argumento é o caminho, o segundo define as permissões (um valor octal como 0755), e o terceiro argumento opcional, quando true, cria recursivamente quaisquer diretórios pai ausentes.
Usando a Função mkdir() em PHP
mkdir("/path/to/my/new/directory", 0755, true);Sem o sinalizador true, mkdir() falha com um aviso se um diretório pai ainda não existir. Em sistemas Unix-like, as permissões reais também são afetadas pelo umask do processo.
Excluindo Diretórios com rmdir()
A função rmdir() exclui um diretório. Ela recebe o caminho do diretório que você deseja remover.
Usando a Função rmdir() em PHP
rmdir("/path/to/my/new/directory");Nota: rmdir() remove apenas diretórios vazios. Para excluir um diretório que ainda contém arquivos, remova os arquivos (e quaisquer subdiretórios) primeiro — por exemplo, iterando o conteúdo com scandir() e chamando unlink() em cada arquivo.
O Substituto Moderno: DirectoryIterator
Para código orientado a objetos, a classe SPL DirectoryIterator é a forma recomendada de percorrer um diretório. Ela é iterável com foreach e fornece informações detalhadas sobre cada entrada — nome, tamanho, tipo e hora de modificação — sem chamadas de função separadas:
<?php
foreach (new DirectoryIterator("/path/to/directory") as $entry) {
if ($entry->isDot()) {
continue; // skip "." and ".."
}
echo $entry->getFilename() . PHP_EOL;
}Para um diretório contendo a.txt, b.log e report.csv, isso imprime:
b.log
report.csv
a.txtisDot() ignora convenientemente tanto . quanto .. em uma única verificação. Para percorrer uma árvore de diretórios inteira, incluindo subpastas, use RecursiveDirectoryIterator junto com RecursiveIteratorIterator.
A Função dir() Legada
Obsoleta: A função
dir()foi descontinuada no PHP 7.4 e removida no PHP 8.0. UseDirectoryIteratorouscandir()no lugar. O exemplo abaixo é fornecido apenas para manutenção de código mais antigo.
A função dir() retorna um objeto Directory que oferece uma forma orientada a objetos de ler o conteúdo de diretórios. Ao contrário de scandir(), que retorna um array simples, dir() retorna um objeto com métodos como read(), rewind() e close(). Note que dir() não é um alias para scandir() — elas servem a propósitos diferentes e retornam tipos de dados diferentes.
Usando a Função dir() em PHP (legado)
<?php
$dir = dir("/path/to/directory");
while (($file = $dir->read()) !== false) {
echo "filename: " . $file . PHP_EOL;
}
$dir->close();Conclusão
PHP oferece várias maneiras de trabalhar com diretórios. Use scandir() ou glob() para listagens rápidas e ordenadas, o trio opendir()/readdir()/closedir() quando quiser transmitir entradas uma por vez, e DirectoryIterator para uma travessia limpa e orientada a objetos. Crie e remova pastas com mkdir() e rmdir(), e recorra a RecursiveDirectoryIterator quando precisar descer para subdiretórios. Para uma visão mais ampla sobre como trabalhar com o sistema de arquivos, consulte os capítulos PHP Directory e PHP Filesystem.