Entendendo o Sistema de Arquivos em PHP
A manipulação de arquivos e diretórios é uma competência fundamental para qualquer desenvolvedor PHP. Seja lendo configurações, armazenando dados do usuário ou gerenciando uploads, você trabalhará constantemente com o sistema de arquivos. PHP oferece funções nativas poderosas que abstraem as complexidades do sistema operacional subjacente.
Antes de começar, compreenda que PHP trabalha com caminhos absolutos e relativos. Um caminho absoluto começa da raiz do sistema (/var/www/html/arquivo.txt), enquanto relativo é baseado no diretório atual do script. Use __DIR__ e __FILE__ (constantes mágicas do PHP) para trabalhar com caminhos de forma robusta e independente do sistema operacional.
Operações Básicas com Arquivos
Criando e Escrevendo em Arquivos
A função file_put_contents() é sua aliada principal para criar ou sobrescrever arquivos. Ela é simples, segura e retorna o número de bytes escritos ou false em caso de erro:
<?php
$caminho = __DIR__ . '/dados.txt';
$conteudo = "Olá, mundo!\nEste é meu primeiro arquivo.";
if (file_put_contents($caminho, $conteudo)) {
echo "Arquivo criado com sucesso!";
} else {
echo "Erro ao criar arquivo!";
}
?>
Para adicionar conteúdo sem sobrescrever (append), use a flag FILE_APPEND:
<?php
$caminho = __DIR__ . '/log.txt';
$mensagem = date('Y-m-d H:i:s') . " - Nova entrada no log\n";
file_put_contents($caminho, $mensagem, FILE_APPEND);
?>
Lendo Arquivos
Para ler um arquivo inteiro, file_get_contents() é o caminho mais direto:
<?php
$caminho = __DIR__ . '/dados.txt';
if (file_exists($caminho)) {
$conteudo = file_get_contents($caminho);
echo $conteudo;
} else {
echo "Arquivo não encontrado!";
}
?>
Se você precisa processar o arquivo linha por linha (útil para arquivos grandes), use fopen() com fgets():
<?php
$caminho = __DIR__ . '/grande_arquivo.txt';
$arquivo = fopen($caminho, 'r');
if ($arquivo) {
while (($linha = fgets($arquivo)) !== false) {
echo trim($linha) . "\n";
}
fclose($arquivo);
}
?>
Manipulação de Diretórios
Criando e Navegando em Diretórios
Para criar um diretório, use mkdir(). O terceiro parâmetro permite criar diretórios aninhados recursivamente:
<?php
$diretorio = __DIR__ . '/uploads/2024/janeiro';
if (!is_dir($diretorio)) {
if (mkdir($diretorio, 0755, true)) {
echo "Diretório criado!";
}
}
?>
Para listar arquivos em um diretório, scandir() retorna um array com todos os itens:
<?php
$diretorio = __DIR__ . '/uploads';
if (is_dir($diretorio)) {
$arquivos = scandir($diretorio);
foreach ($arquivos as $arquivo) {
if ($arquivo !== '.' && $arquivo !== '..') {
$caminho_completo = $diretorio . '/' . $arquivo;
$tipo = is_file($caminho_completo) ? 'Arquivo' : 'Diretório';
echo "$arquivo ($tipo)\n";
}
}
}
?>
Deletando e Movendo
Para remover um arquivo, unlink() é suficiente:
<?php
$arquivo = __DIR__ . '/temp.txt';
if (file_exists($arquivo) && is_file($arquivo)) {
if (unlink($arquivo)) {
echo "Arquivo deletado!";
}
}
?>
Para remover um diretório vazio, use rmdir(). Se contém arquivos, você precisa deletá-los primeiro ou usar uma solução recursiva:
<?php
function deletar_diretorio_recursivo($diretorio) {
if (!is_dir($diretorio)) return false;
$arquivos = scandir($diretorio);
foreach ($arquivos as $arquivo) {
if ($arquivo !== '.' && $arquivo !== '..') {
$caminho = $diretorio . '/' . $arquivo;
is_dir($caminho) ? deletar_diretorio_recursivo($caminho) : unlink($caminho);
}
}
return rmdir($diretorio);
}
deletar_diretorio_recursivo(__DIR__ . '/pasta_temp');
?>
Para mover ou renomear, rename() funciona para arquivos e diretórios:
<?php
$origem = __DIR__ . '/arquivo_antigo.txt';
$destino = __DIR__ . '/arquivo_novo.txt';
if (rename($origem, $destino)) {
echo "Arquivo movido com sucesso!";
}
?>
Informações e Validações
Verificando Propriedades
Antes de manipular arquivos, sempre valide sua existência e tipo. PHP oferece funções específicas e eficientes:
<?php
$caminho = __DIR__ . '/dados.txt';
echo "Existe? " . (file_exists($caminho) ? 'Sim' : 'Não') . "\n";
echo "É arquivo? " . (is_file($caminho) ? 'Sim' : 'Não') . "\n";
echo "É diretório? " . (is_dir($caminho) ? 'Sim' : 'Não') . "\n";
echo "Legível? " . (is_readable($caminho) ? 'Sim' : 'Não') . "\n";
echo "Gravável? " . (is_writable($caminho) ? 'Sim' : 'Não') . "\n";
echo "Tamanho: " . filesize($caminho) . " bytes\n";
echo "Última modificação: " . date('d/m/Y H:i:s', filemtime($caminho)) . "\n";
?>
Exemplo Prático: Upload Seguro
Combine validações para criar um sistema de upload robusto:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['arquivo'])) {
$arquivo = $_FILES['arquivo'];
$extensoes_permitidas = ['jpg', 'png', 'pdf'];
$tamanho_maximo = 5 * 1024 * 1024; // 5MB
$extensao = strtolower(pathinfo($arquivo['name'], PATHINFO_EXTENSION));
if ($arquivo['size'] > $tamanho_maximo) {
echo "Arquivo muito grande!";
} elseif (!in_array($extensao, $extensoes_permitidas)) {
echo "Extensão não permitida!";
} elseif ($arquivo['error'] !== UPLOAD_ERR_OK) {
echo "Erro no upload!";
} else {
$destino = __DIR__ . '/uploads/' . uniqid() . '.' . $extensao;
if (move_uploaded_file($arquivo['tmp_name'], $destino)) {
echo "Upload realizado com sucesso!";
}
}
}
?>
Conclusão
Dominar manipulação de arquivos em PHP é essencial para qualquer desenvolvedor. Os três pontos principais que você deve internalizar:
-
Use as funções nativas apropriadas:
file_put_contents()efile_get_contents()para operações simples,fopen()para arquivos grandes, e sempre valide comfile_exists(),is_file()eis_writable(). -
Segurança em primeiro lugar: Sempre valide entradas, use caminhos absolutos com
__DIR__, implemente restrições de tamanho e tipo, e sanitize nomes de arquivo antes de armazenar. -
Estruture seus diretórios logicamente: Crie estruturas organizadas com
mkdir()recursivo, separe uploads temporários de permanentes, e implemente limpeza de arquivos antigos regularmente.
A prática é crucial — comece criando scripts simples que leiam, criem e deletem arquivos antes de avançar para sistemas complexos como gerenciadores de mídia.