PHP Directory
PHP Directory: Guia de referência completo para desenvolvedores PHP.
O PHP inclui um conjunto de funções de diretório nativas que permitem aos seus scripts inspecionar, criar, ler e remover pastas no sistema de arquivos do servidor — sem precisar executar comandos do sistema operacional. Esta página explica o que cada função principal faz, quando utilizá-la e os erros comuns a evitar.
Esta é uma referência complementar a PHP File Handling e à referência mais ampla do PHP Filesystem: os arquivos estão dentro de diretórios, portanto os dois tópicos são quase sempre utilizados juntos.
Por que as operações de diretório são importantes
Praticamente toda aplicação não trivial acessa o sistema de arquivos. Você precisa das funções de diretório para:
- Organizar arquivos enviados — separar uploads de usuários em pastas por usuário ou por data (veja PHP File Upload).
- Criar a estrutura do projeto dinamicamente — gerar pastas de cache, log ou exportação na primeira vez que forem necessárias.
- Iterar sobre conteúdo — listar todos os templates, imagens ou arquivos de dados de uma pasta para processá-los em lote.
- Fazer limpeza — excluir diretórios temporários após a conclusão de uma tarefa.
Como essas funções fazem parte do núcleo do PHP, funcionam da mesma forma no Linux, macOS e Windows (com / aceito como separador em todos os casos), o que as torna mais portáveis do que executar mkdir ou ls por meio de exec().
Funções principais de diretório
| Função | Finalidade |
|---|---|
mkdir($path, $mode, $recursive) | Cria um diretório. Passe true para $recursive para criar diretórios pai aninhados. |
rmdir($path) | Remove um diretório — ele deve estar vazio antes. |
is_dir($path) | Retorna true se o caminho existir e for um diretório. |
scandir($path) | Retorna um array com todas as entradas de um diretório (incluindo . e ..). |
opendir() / readdir() / closedir() | Abre um identificador de diretório e lê as entradas uma por vez. |
getcwd() | Retorna o diretório de trabalho atual. |
chdir($path) | Altera o diretório de trabalho atual. |
scandir() vs. opendir()
Ambas listam o conteúdo de um diretório, mas atendem a necessidades diferentes:
scandir()carrega todas as entradas em um array de uma vez. É concisa e fácil de ordenar, mas usa memória proporcional ao número de arquivos. Ideal para pastas de tamanho pequeno a médio.opendir()/readdir()transmitem as entradas uma a uma. Isso mantém o uso de memória constante mesmo para diretórios com dezenas de milhares de arquivos. Ideal para pastas muito grandes.
Ambas incluem as entradas especiais . (atual) e .. (pai) — na maioria das vezes você vai querer ignorá-las.
Exemplo: criar um diretório e listá-lo
Este script verifica se um diretório existe, cria-o (junto com quaisquer pastas pai ausentes) se não existir e, em seguida, imprime seu conteúdo:
<?php
$dir = 'uploads/images';
// Create the directory and any missing parents if it doesn't exist
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
echo "Directory created: $dir\n";
}
// List directory contents, skipping the . and .. entries
$files = scandir($dir);
echo "Contents of $dir:\n";
foreach ($files as $file) {
if ($file !== '.' && $file !== '..') {
echo "- $file\n";
}
}
?>O terceiro argumento de mkdir() (true) é a flag recursive: sem ela, mkdir('uploads/images') falha se uploads ainda não existir. O 0755 é um modo de permissão octal (o proprietário pode ler/gravar/executar, outros podem ler/executar) e é ignorado no Windows.
Exemplo: streaming com opendir()
Para diretórios grandes, leia as entradas uma de cada vez em vez de construir um array completo:
<?php
$dir = __DIR__;
if ($handle = opendir($dir)) {
while (($entry = readdir($handle)) !== false) {
if ($entry !== '.' && $entry !== '..') {
$type = is_dir("$dir/$entry") ? 'dir ' : 'file';
echo "[$type] $entry\n";
}
}
closedir($handle);
}
?>Observe a comparação estrita !== false: um arquivo literalmente chamado "0" é falso, portanto um while ($entry = readdir(...)) frouxo encerraria cedo. Sempre compare explicitamente com false.
Removendo diretórios
rmdir() só exclui um diretório vazio. Para remover um que ainda contém arquivos, exclua o conteúdo primeiro — tipicamente com um auxiliar recursivo:
<?php
function removeDir(string $dir): void {
foreach (scandir($dir) as $entry) {
if ($entry === '.' || $entry === '..') {
continue;
}
$path = "$dir/$entry";
is_dir($path) ? removeDir($path) : unlink($path);
}
rmdir($dir);
}
?>Esta função percorre cada entrada, recursando em subdiretórios e chamando unlink() nos arquivos, de modo que o diretório esteja vazio quando rmdir() for executado.
Armadilhas comuns
mkdir()sem a flag recursive falha se alguma pasta pai estiver ausente. Passetrueao criar caminhos aninhados.- As permissões são subtraídas pelo
umask— o modo real é$mode & ~umask(), portanto0777pode resultar em0755. rmdir()em uma pasta não vazia retornafalsee emite um aviso. Esvazie-a primeiro.scandir()inclui.e..— filtre-os antes de processar.- Caminhos relativos dependem de
getcwd(), que é o diretório de trabalho do script, não a localização do arquivo. Use__DIR__para ancorar caminhos ao arquivo atual.
Fluxo de trabalho de diretório em resumo
graph TD
A[Check Directory] --> B{Exists?}
B -->|No| C[mkdir]
B -->|Yes| D[scandir / opendir]
C --> E[Create Subdirectories]
D --> F[Read Entries]
F --> G[Process Files]
G --> H[close / rmdir]Resumo
As funções de diretório do PHP oferecem uma forma portável e nativa de gerenciar pastas: mkdir() e rmdir() criam e removem diretórios, is_dir() os verifica, e scandir() ou opendir()/readdir() listam seu conteúdo. Use scandir() em pastas pequenas pela sua simplicidade, e o streaming com opendir() em pastas grandes para manter o uso de memória constante. Combine essas funções com as funções de arquivo PHP e o tratamento de arquivos para criar recursos robustos de upload, cache e exportação.