tmpfile()
Функция tmpfile() в PHP создаёт временный файл с уникальным именем, открывает его для чтения и записи и автоматически удаляет при закрытии.
Введение
Когда PHP-скрипту нужно место для временного хранения данных, которые важны лишь на время текущего запроса — буфер, слишком большой для памяти, CSV-файл, который нужно отдать браузеру, или вывод внешней команды — на помощь приходит временный файл. Функция tmpfile() решает эту задачу одним вызовом: она создаёт уникальный файл в системной временной директории, открывает его для чтения и записи и возвращает файловый дескриптор. Главное достоинство — файл удаляется автоматически.
В этой главе рассматриваются синтаксис, поведение автоматической очистки, которое делает tmpfile() особенной, случаи использования в сравнении с tempnam(), а также несколько запускаемых примеров с типичными подводными камнями.
Что такое временный файл?
Временный файл — это файл, который программа использует как рабочее пространство и не собирается хранить после завершения работы. Он находится во временной директории операционной системы (/tmp на Linux/macOS, C:\Windows\Temp или путь из переменной окружения TEMP на Windows). Поскольку эту директорию используют многие процессы, временные файлы должны иметь уникальные имена, чтобы два скрипта не затёрли файлы друг друга — tmpfile() обеспечивает эту уникальность автоматически.
Понимание функции tmpfile()
Функция tmpfile() создаёт временный файл с уникальным именем в системной временной директории и открывает его для чтения и записи в режиме w+ (файл начинается пустым, и вы можете как записывать в него данные, так и читать обратно). Она не принимает параметров.
Ключевая особенность — автоматическая очистка. Временный файл удаляется, когда:
- вы закрываете дескриптор с помощью
fclose(), или - скрипт завершается и дескриптор выходит из области видимости.
Благодаря этому вам почти никогда не нужно удалять файл вручную. Обратная сторона — tmpfile() не сообщает путь к файлу: дескриптор является единственной ссылкой, которую вы получаете. Если вам нужно известное имя файла для передачи другой программе, используйте tempnam().
Синтаксис функции tmpfile()
Синтаксис функции tmpfile() выглядит следующим образом:
tmpfile(): resource|falseФункция не принимает аргументов и возвращает:
- файловый дескриптор (resource), позиционированный в начало пустого файла при успехе, или
falseпри ошибке — например, если временная директория недоступна для записи.
Всегда проверяйте возвращаемое значение перед использованием дескриптора: передача false в функции вроде fwrite() вызовет TypeError в PHP 8+.
Примеры использования tmpfile()
Пример 1: Запись, чтение и автоматическая очистка
Самый распространённый шаблон: открыть временный файл, записать в него данные, перемотать указатель и прочитать обратно. Обратите внимание на вызов rewind() — после записи внутренний указатель находится в конце данных, поэтому без перемотки fread() вернёт пустую строку.
<?php
$handle = tmpfile();
if ($handle === false) {
die('Failed to create temporary file');
}
fwrite($handle, 'Example data');
rewind($handle); // move pointer back to the beginning
echo fread($handle, 1024); // read up to 1024 bytes
fclose($handle); // closing also deletes the fileВывод:
Example dataФайл удаляется в момент выполнения fclose(), поэтому ручная очистка не требуется.
Пример 2: Получение реального пути к временному файлу
Хотя tmpfile() скрывает имя файла, его можно узнать через метаданные потока с помощью stream_get_meta_data(). Это удобно для логирования или отладки — например, чтобы убедиться, что файл действительно исчезает.
<?php
$handle = tmpfile();
$meta = stream_get_meta_data($handle);
$path = $meta['uri'];
echo 'Temp file exists before close: ';
echo file_exists($path) ? 'yes' : 'no';
echo "\n";
fclose($handle);
echo 'Temp file exists after close: ';
echo file_exists($path) ? 'yes' : 'no';
echo "\n";Вывод:
Temp file exists before close: yes
Temp file exists after close: noПример 3: Буферизация строк CSV перед отправкой
Практический сценарий: формирование CSV во временном файле с помощью fputcsv(), а затем чтение всего содержимого для возврата или потоковой передачи. Это позволяет держать большие данные вне памяти, собирая их построчно.
<?php
$rows = [
['Name', 'Role'],
['Ada', 'Engineer'],
['Linus', 'Maintainer'],
];
$handle = tmpfile();
foreach ($rows as $row) {
fputcsv($handle, $row);
}
rewind($handle);
echo stream_get_contents($handle); // read everything from the pointer to EOF
fclose($handle);Вывод:
Name,Role
Ada,Engineer
Linus,Maintainertmpfile() vs tempnam()
Обе функции создают временные файлы, но решают разные задачи:
| Аспект | tmpfile() | tempnam() |
|---|---|---|
| Возвращает | Открытый дескриптор файла | Имя файла (string) |
| Открывает файл? | Да (w+) | Нет — вы сами вызываете fopen() |
| Автоудаление? | Да, при закрытии / завершении скрипта | Нет — нужно вызвать unlink() вручную |
| Известен путь? | Только через stream_get_meta_data() | Да, напрямую |
Практическое правило: используйте tmpfile() для самодостаточных временных данных в рамках одного скрипта; используйте tempnam(), когда нужен именованный файл для передачи другому процессу или для хранения после запроса.
Распространённые ошибки
- Забыть вызвать
rewind(). После записи указатель находится в конце. Чтение без перемотки ничего не вернёт. - Не проверять возвращаемое значение. Если временная директория доступна только для чтения,
tmpfile()вернётfalse; всегда защищайтесь от этого. - Ожидать, что файл сохранится. После закрытия дескриптора файл исчезает — скопируйте данные заранее (через
fopen()в постоянный путь,file_put_contents()и т.д.), если они нужны после.
Заключение
Функция tmpfile() — самый простой способ получить приватный, автоматически удаляемый рабочий файл в PHP. Она возвращает дескриптор для чтения и записи, безопасно размещает файл в системной временной директории и удаляет его в момент закрытия дескриптора или завершения скрипта — никакой ручной работы по уборке не требуется. Используйте её, когда нужно кратковременное хранилище и имя файла не важно; используйте tempnam(), когда имя важно.