Manipulação de arquivos
Bancos de dados armazenam dados estruturados; arquivos armazenam dados não estruturados — logs, arquivos de configuração, relatórios em CSV, imagens enviadas pelos usuários. Esta lição oferece a você controle total sobre arquivos e diretórios em PHP.
1. Leitura de arquivos
<?php
// Method 1: file_get_contents() — read an entire file in one line
$content = file_get_contents('hello.txt');
echo $content;
// Method 2: fopen + fread — streamed reading (for large files)
$handle = fopen('hello.txt', 'r');
$content = fread($handle, filesize('hello.txt'));
fclose($handle);
// Method 3: Read line by line (most memory-efficient)
$handle = fopen('data.txt', 'r');
while (($line = fgets($handle)) !== false) {
echo trim($line) . "<br>";
}
fclose($handle);
// Method 4: file() — read all lines into an array at once
$lines = file('data.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
print_r($lines);
?>
| Método | Ideal para | Memória |
|---|---|---|
file_get_contents() |
Arquivos pequenos (config, JSON) | Todos de uma vez |
fopen + fread |
Arquivos médios | Controlado |
fopen + fgets |
Arquivos grandes (logs, CSV) | Baixo |
file() |
Arquivos pequenos processados por linha | Todos de uma vez |
2. Gravação de arquivos
<?php
// file_put_contents() — write a file in one line
file_put_contents('notes.txt', "Today I learned PHP file handling\n");
// Append mode (third parameter: FILE_APPEND)
file_put_contents('notes.txt', "Now I can append content\n", FILE_APPEND);
// Exclusive lock for writing (prevents concurrent conflicts)
file_put_contents('counter.txt', $count, LOCK_EX);
// fwrite — fine-grained control
$handle = fopen('log.txt', 'a'); // 'a' = append mode
fwrite($handle, date("Y-m-d H:i:s") . " — User logged in\n");
fclose($handle);
?>
▶ Exemplo: Sistema simples de registro de logs
<?php
class Logger {
public function __construct(
private string $logFile
) {}
public function info(string $message): void {
$this->write('INFO', $message);
}
public function error(string $message): void {
$this->write('ERROR', $message);
}
public function warning(string $message): void {
$this->write('WARNING', $message);
}
private function write(string $level, string $message): void {
$time = date("Y-m-d H:i:s");
$line = "[{$time}] [{$level}] {$message}\n";
file_put_contents($this->logFile, $line, FILE_APPEND | LOCK_EX);
}
public function getRecent(int $lines = 20): array {
if (!file_exists($this->logFile)) {
return [];
}
$all = file($this->logFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
return array_slice($all, -$lines);
}
}
$log = new Logger('app.log');
$log->info('App started');
$log->warning('Config file not found, using defaults');
$log->error('Database connection timed out');
$log->info('App finished');
echo "<h3>Recent Logs</h3><pre>" . implode("\n", $log->getRecent(10)) . "</pre>";
?>
3. Detecção de arquivos
<?php
$file = 'test.txt';
// Existence checks
var_dump(file_exists($file)); // bool
var_dump(is_file($file)); // Also check it's a file (not a directory)
var_dump(is_dir($file)); // Check if it's a directory
// Read/Write checks
var_dump(is_readable($file)); // Can it be read?
var_dump(is_writable($file)); // Can it be written to?
// File information
echo filesize($file) . " bytes<br>"; // Size
echo filemtime($file); // Last modified time (Unix timestamp)
echo date("Y-m-d H:i:s", filemtime($file)) . "<br>"; // Formatted date
echo pathinfo($file, PATHINFO_EXTENSION); // txt
?>
▶ Exemplo: Cache de arquivos
<?php
class FileCache {
private string $cacheDir;
public function __construct(string $dir = 'cache') {
$this->cacheDir = $dir;
if (!is_dir($this->cacheDir)) {
mkdir($this->cacheDir, 0755, true);
}
}
public function get(string $key, int $ttl = 3600): mixed {
$file = "{$this->cacheDir}/{$key}.cache";
if (!file_exists($file)) return null;
if (time() - filemtime($file) > $ttl) {
unlink($file);
return null;
}
return unserialize(file_get_contents($file));
}
public function set(string $key, mixed $value): void {
$file = "{$this->cacheDir}/{$key}.cache";
file_put_contents($file, serialize($value), LOCK_EX);
}
}
$cache = new FileCache();
$cache->set('config', ['app_name' => 'MyBlog', 'version' => '1.0']);
print_r($cache->get('config'));
?>
4. Referência rápida sobre operações com arquivos
<?php
$src = 'source.txt';
$dst = 'backup.txt';
// Copy
copy($src, $dst);
// Rename / Move
rename($src, 'new-name.txt');
rename('/tmp/upload.txt', '/var/www/files/upload.txt'); // Move
// Delete
unlink('old-file.txt');
// Directory operations
mkdir('new-folder', 0755, true); // true = recursive creation
rmdir('empty-folder'); // Only deletes empty directories
// Traverse a directory
foreach (scandir('uploads') as $item) {
if ($item !== '.' && $item !== '..') {
echo "{$item} — " . (is_dir("uploads/{$item}") ? 'Directory' : 'File') . "<br>";
}
}
// Use glob for pattern-based file search
$images = glob('uploads/*.{jpg,png,gif}', GLOB_BRACE);
echo "Found " . count($images) . " images";
?>
5. Leitura e gravação de arquivos CSV
O CSV é o formato universal para a troca de dados — o Excel consegue abri-lo, e qualquer linguagem de programação consegue lê-lo e gravá-lo:
<?php
// === Writing CSV ===
$data = [
['Name', 'Age', 'City'],
['John', 25, 'Beijing'],
['Jane', 22, 'Shanghai'],
['Bob', 28, 'Guangzhou'],
];
$handle = fopen('users.csv', 'w');
// Write UTF-8 BOM (helps Excel recognize the encoding correctly)
fwrite($handle, "\xEF\xBB\xBF");
foreach ($data as $row) {
fputcsv($handle, $row);
}
fclose($handle);
echo "CSV file generated ✅<br>";
// === Reading CSV ===
$handle = fopen('users.csv', 'r');
// Skip BOM
fseek($handle, 3);
// Read headers
$headers = fgetcsv($handle);
while (($row = fgetcsv($handle)) !== false) {
// Use headers as keys
$item = array_combine($headers, $row);
echo "{$item['Name']}, {$item['Age']} years old, lives in {$item['City']}<br>";
}
fclose($handle);
?>
▶ Exemplo: Exportação de dados em CSV
<?php
function exportToCSV(array $data, string $filename): void {
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename={$filename}");
$output = fopen('php://output', 'w');
fwrite($output, "\xEF\xBB\xBF"); // BOM
// Headers
if (!empty($data)) {
fputcsv($output, array_keys($data[0]));
}
// Data
foreach ($data as $row) {
fputcsv($output, $row);
}
fclose($output);
}
// exportToCSV($usersData, 'users_export.csv');
?>
6. Bloqueio de arquivos (prevenção de gravações simultâneas)
<?php
class Counter {
private string $file;
public function __construct(string $file = 'counter.dat') {
$this->file = $file;
if (!file_exists($this->file)) {
file_put_contents($this->file, 0);
}
}
public function increment(): int {
$handle = fopen($this->file, 'c+');
// Acquire an exclusive lock (other processes wait)
if (flock($handle, LOCK_EX)) {
$count = (int)fread($handle, 100);
$count++;
// Go back to the beginning of the file
fseek($handle, 0);
ftruncate($handle, 0); // Clear it
fwrite($handle, (string)$count);
flock($handle, LOCK_UN); // Unlock
fclose($handle);
return $count;
}
fclose($handle);
return -1;
}
}
?>
❓ Perguntas Frequentes
P: Como faço para escolher entre
file_get_contents()efopen + fgets? R: Usefile_get_contents()para arquivos pequenos (<1 MB) — basta uma linha e pronto. Usefgets()para ler linha por linha em arquivos grandes (dezenas de milhares de linhas de log) — ele consome pouca memória. Se você não souber o tamanho, comece comfopen.
P: Os caracteres chineses aparecem distorcidos no Excel? R: Adicione um BOM UTF-8 (
"\xEF\xBB\xBF") no início do arquivo CSV. Por padrão, o Excel lê os arquivos usando a codificação local — o BOM indica que o arquivo está no formato UTF-8.
P: O bloqueio de arquivos com
flocké realmente necessário? R: Com certeza, quando vários processos leem e gravam o mesmo arquivo simultaneamente. Contadores, caches e logs podem sofrer com condições de corrida, nas quais os valores são lidos depois que outro processo já os modificou — sem bloqueio.
📖 Resumo
file_get_contents()lê um arquivo em uma linha;file_put_contents()grava um arquivo em uma linhafopen + fgetslê linha por linha — ideal para arquivos grandesfile_put_contents($file, $data, FILE_APPEND | LOCK_EX)acrescenta com segurançafile_exists()/is_readable()/is_writable()— verifique antes de operar- CSV:
fputcsv()para gravação,fgetcsv()para leitura; o BOM evita que o texto fique distorcido no Excel flock($handle, LOCK_EX)oferece bloqueio exclusivo para evitar conflitos de gravação simultânea
📝 Exercícios
- Crie um contador de visitantes: a cada atualização da página, a contagem aumenta em 1, sendo armazenada em um arquivo.
- Crie um livro de visitas simples: um formulário envia uma mensagem → acrescenta-a a um arquivo → lê e exibe todas as mensagens do arquivo (com registros de data e hora).
- Exporte a tabela de usuários para um arquivo CSV (leia os dados do MySQL → gere um arquivo CSV → forneça um link para download).



