tempnam()
Функция tempnam() в PHP создаёт временный файл с уникальным именем и возвращает полный путь к нему.
Введение
tempnam() создаёт временный файл с уникальным именем и возвращает полный путь к нему. Важно отметить, что функция не просто генерирует имя — она фактически создаёт файл на диске (пустой, с режимом 0600), поэтому исключена ситуация, при которой два процесса могут выбрать одно и то же имя. Используйте её, когда скрипту нужно временное пространство на диске: буферизация загрузки, генерация отчёта перед его потоковой передачей или передача пути внешней команде.
В этой главе рассматриваются синтаксис, возвращаемое значение, место создания файла, типичные ошибки в продакшене и правила очистки после работы.
Синтаксис
tempnam(string $directory, string $prefix): string|false| Параметр | Описание |
|---|---|
$directory | Директория, в которой должен быть создан файл. Если она не существует или недоступна для записи, PHP переключается на системную временную директорию (sys_get_temp_dir()). |
$prefix | Префикс для сгенерированного имени файла. На большинстве систем используются только первые 63 символа; в Windows — только первые 3. |
Возвращаемое значение: полный путь к вновь созданному файлу (например, /tmp/example_aB3xYz) или false в случае ошибки.
Создание временного файла
<?php
$tempFile = tempnam(sys_get_temp_dir(), 'example_');
echo $tempFile;
// e.g. /tmp/example_8gKq2Psys_get_temp_dir() возвращает системную временную директорию (/tmp в Linux/macOS, путь TEMP в Windows), что более переносимо, чем жёстко указывать /tmp.
Запись в файл и чтение из него
tempnam() лишь предоставляет путь к пустому файлу — для записи данных его нужно открыть:
<?php
$tempFile = tempnam(sys_get_temp_dir(), 'report_');
// Write some data
file_put_contents($tempFile, "Line 1\nLine 2\n");
// Read it back
echo file_get_contents($tempFile);
// Line 1
// Line 2
// Clean up when you're done
unlink($tempFile);Поскольку tempnam() не удаляет файл автоматически, всегда удаляйте его с помощью unlink() после завершения работы — иначе временные файлы будут накапливаться.
Резервное поведение
Если $directory не существует или недоступна для записи, tempnam() не завершается с ошибкой — она молча создаёт файл в системной временной директории. Это означает, что возвращаемый путь может не находиться в запрошенной директории, поэтому никогда не предполагайте конкретное расположение:
<?php
// /no/such/dir doesn't exist
$tempFile = tempnam('/no/such/dir', 'data_');
// File is created in sys_get_temp_dir(), not /no/such/dir
echo dirname($tempFile) === sys_get_temp_dir() ? 'fell back' : $tempFile;
// fell backВсегда используйте возвращённый путь для последующих операций вместо того, чтобы восстанавливать его из $directory и $prefix.
tempnam() и tmpfile()
Обе функции создают уникальный временный файл, но служат разным целям:
tempnam()возвращает путь (строку). Файл существует до тех пор, пока вы не вызоветеunlink(), и путь можно передавать другим функциям или внешним программам.tmpfile()возвращает открытый дескриптор файла, который автоматически удаляется при закрытии дескриптора или завершении скрипта. Используйте его, когда нужен только дескриптор и требуется автоматическая очистка.
Выбирайте tempnam(), когда нужно имя файла; выбирайте tmpfile(), когда нужен самоочищающийся рабочий дескриптор.
Типичные ошибки
- Файл создаётся сразу. Файл уже существует (пустым) после вызова, поэтому
file_exists()для результата всегда возвращаетtrue. Чтобы обнаружить ошибку, сравнивайте со значениемfalse. - Всегда вызывайте unlink. Временные файлы не удаляются автоматически. Сопровождайте каждый вызов
tempnam()вызовомunlink(), желательно в блокеfinally. - Не доверяйте директории. Из-за резервного поведения файл может оказаться не там, где вы просили. Используйте возвращённый путь.
- Префикс обрезается. Длинные префиксы урезаются (до 3 символов в Windows), поэтому не рассчитывайте на присутствие полного префикса в имени файла.
Заключение
tempnam() безопасно создаёт уникально названный пустой временный файл и возвращает его путь. Помните, что функция создаёт файл (а не только имя), может переключиться на системную временную директорию и никогда не удаляет файл сама — поэтому всегда работайте с возвращённым путём и вызывайте unlink() по завершении. Если нужен самоудаляющийся дескриптор, предпочтите tmpfile().