Как управлять временными файлами в PHP: от простых решений до продвинутых сценариев
Основы работы с временными файлами в PHP
Временные файлы используются для хранения промежуточных данных, которые не нужны после завершения операции. PHP предлагает несколько подходов для их создания и управления, каждый со своими особенностями.
Как создать временный файл с автоматическим удалением?
Наиболее простой и безопасный способ - функция tmpfile(). Она создаёт файл с уникальным именем в системной временной директории и возвращает файловый указатель. Файл автоматически удаляется при закрытии указателя или завершении скрипта.
$handle = tmpfile();
fwrite($handle, 'Временные данные');
rewind($handle);
echo stream_get_contents($handle);
fclose($handle); // файл удаляется
Index php path (пути файлов в php)
Типичная ошибка: попытка получить путь к файлу. Решение: использовать stream_get_meta_data($handle)['uri'], но файл уже может быть недоступен после закрытия.
Этот вариант подходит для потоковой передачи данных, временного кэширования результатов запросов или работы с загрузкой файлов.
Как создать временный файл с известным именем?
Для случаев, когда необходимо получить путь к файлу (например, для передачи внешней программе), используется пара sys_get_temp_dir() и tempnam(). Файл создаётся, но не удаляется автоматически.
$tmpDir = sys_get_temp_dir();
$tmpFile = tempnam($tmpDir, 'myapp_');
file_put_contents($tmpFile, 'Данные для внешней утилиты');
// ... работа с файлом ...
unlink($tmpFile); // обязательно удалить вручную
Php tmp files (временные файлы php)
Проблема: забытый вызов unlink() приводит к засорению диска. Решение: использовать деструктор или зарегистрировать функцию очистки через register_shutdown_function().
Применяется при интеграции с библиотеками, требующими файловый путь (например, ImageMagick), или для передачи файлов между скриптами.
Как хранить временные данные в памяти, а не на диске?
Если объём данных невелик, эффективнее использовать потоковый wrapper php://temp. Он автоматически переключается на диск при превышении лимита памяти (по умолчанию 2 МБ).
$fp = fopen('php://temp', 'r+');
fwrite($fp, 'Быстрый доступ в памяти');
rewind($fp);
echo stream_get_contents($fp);
fclose($fp);
Edit file php (редактирование php файла)
Идеально для временных строк, сериализованных данных или лёгких кэшей.
Как получить системную временную директорию?
Функция sys_get_temp_dir() возвращает путь к временной папке, определённой окружением (например, /tmp в Linux, C:\Windows\Temp в Windows).
echo sys_get_temp_dir();
Это полезно для собственных реализаций временных файлов или проверки доступности места.
Общие проблемы: недостаточное место на диске, конфликты имён при параллельных запросах, неправильные права доступа. Рекомендации: всегда проверять возвращаемые значения (false при ошибке), использовать уникальные префиксы, явно удалять файлы после использования.
Расширенные примеры работы с временными файлами
Пример 1: Временный файл для загрузки и обработки изображения
Используется tmpfile() для сохранения загруженного файла, затем передача во внешнюю библиотеку GD.
// Имитация загруженного файла
$uploaded = tmpfile();
fwrite($uploaded, file_get_contents('https://via.placeholder.com/150'));
// Получение пути (до закрытия)
$path = stream_get_meta_data($uploaded)['uri'];
// Обработка через GD
$image = imagecreatefromstring(file_get_contents($path));
if ($image) {
$thumb = imagescale($image, 100, 100);
imagepng($thumb, 'thumbnail.png');
imagedestroy($image);
imagedestroy($thumb);
}
fclose($uploaded); // временный файл удалён
Проблема: stream_get_meta_data() может не дать пути при использовании php://temp. Решение: применять tempnam() если нужен путь.
Пример 2: Временная директория для множества файлов
Создание временной папки для распаковки архива с последующим удалением.
$tmpDir = sys_get_temp_dir() . '/myapp_' . uniqid();
mkdir($tmpDir, 0700, true);
// Распаковка
$zip = new ZipArchive();
$zip->open('archive.zip');
$zip->extractTo($tmpDir);
$zip->close();
// Получение списка файлов
$files = scandir($tmpDir);
print_r($files);
// Очистка
array_map('unlink', glob("$tmpDir/*.*"));
rmdir($tmpDir);
Array
(
[0] => .
[1] => ..
[2] => file1.txt
[3] => image.png
)
Пример 3: Использование php://temp с пользовательским лимитом памяти
Можно изменить максимальный размер до переключения на диск, передав параметр через строку запроса.
// Лимит 1 МБ, после - переход на диск
$fp = fopen('php://temp/maxmemory:1048576', 'r+');
fwrite($fp, str_repeat('X', 2*1024*1024)); // 2 МБ, превышает лимит
rewind($fp);
echo 'Размер в памяти: ' . (fstat($fp)['size'] / 1024 / 1024) . ' MB';
fclose($fp);
Размер в памяти: 2 MB
Файл всё равно остался в памяти? На самом деле после превышения лимита данные сбрасываются на диск, но PHP скрывает это. Для проверки можно использовать stream_get_meta_data($fp)['stream_type'].
Пример 4: Безопасное создание временного файла с уникальным именем и автоматическим удалением
Комбинация tempnam() и register_shutdown_function() для гарантированной очистки.
class TempFile {
protected string $path;
public function __construct(string $prefix = 'tmp_') {
$this->path = tempnam(sys_get_temp_dir(), $prefix);
register_shutdown_function(function () {
if (file_exists($this->path)) {
unlink($this->path);
}
});
}
public function getPath(): string { return $this->path; }
public function __destruct() {
// Дублируем удаление на случай, если shutdown не сработал
if (file_exists($this->path)) {
unlink($this->path);
}
}
}
$temp = new TempFile('img_');
file_put_contents($temp->getPath(), 'data');
echo $temp->getPath();
// После выхода из скрипта файл удалится
Пример 5: Временный файл для передачи данных между процессами
Создание уникального файла, запись, затем запуск внешней команды.
$tmpFile = tempnam(sys_get_temp_dir(), 'proc_');
file_put_contents($tmpFile, 'input data');
$output = shell_exec("cat $tmpFile | wc -w");
echo "Количество слов: $output";
unlink($tmpFile);
Количество слов: 2
Пример 6: Генерация PDF во временный файл и отправка пользователю
Используется tmpfile() для генерации контента, затем вывод через readfile() сразу после записи.
$pdf = tmpfile();
// Предположим, библиотека TCPDF работает с файлами
// $pdf->Output($pdfPath, 'F');
// Имитация:
fwrite($pdf, '%PDF-1.4 ... content ...');
// Отправка заголовков
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="report.pdf"');
rewind($pdf);
fpassthru($pdf);
fclose($pdf); // удаляется
Такой подход позволяет не хранить PDF на диске после отправки.