php create temp file
tmpfile
(PHP 4, PHP 5, PHP 7, PHP 8)
tmpfile — Создаёт временный файл
Описание
Создаёт временный файл с уникальным именем, открывая его в режиме чтения и записи (w+) и возвращает файловый указатель.
Этот файл автоматически удаляется после закрытия (например, путём вызова функции fclose() или если не осталось ни одной ссылки на указатель файла, возвращаемый tmpfile() ), или при завершении работы скрипта.
Если скрипт неожиданно завершится, временный файл не может быть удалён.
Список параметров
У этой функции нет параметров.
Возвращаемые значения
Возвращает дескриптор файла, аналогичный тому, который возвращает функция fopen() для новых файлов или false в случае возникновения ошибки.
Примеры
Пример #1 Пример использования функции tmpfile()
Результат выполнения данного примера:
Смотрите также
User Contributed Notes 7 notes
To get the underlying file path of a tmpfile file pointer:
I found this function useful when uploading a file through FTP. One of the files I was uploading was input from a textarea on the previous page, so really there was no «file» to upload, this solved the problem nicely:
And I’m not sure if you need the fseek($temp,0); in there either, just leave it unless you know it doesn’t effect it.
Since this function may not be working in some environments, here is a simple workaround:
register_shutdown_function(function() use($file) <
unlink($file);
>);
at least on Windows 10 with php 7.3.7, and Debian Linux with php 7.4.2,
(an important distinction when working on Windows systems)
Where you might be getting confused is in some systems’ requirement that one seek or flush between reading and writing the same file. fflush() satisfies that prerequisite, but it doesn’t do anything about the file pointer, and in this case the file pointer needs moving.
Create a temp file with a specific extension using php
How do I create a temporary file with a specified extension in php. I came across tempnam() but using it the extension can’t be specified.
7 Answers 7
Easiest way i have found is to create tempfile and then just rename it. For example:
This might simulate mkstemp() (see http://linux.die.net/man/3/mkstemp) a bit, achieving what you want to do:
The same as tempnam() except the additional parameter:
That ‘p’ at the end of the name stands for ‘postfix’.
Rename does it, find the extension with pathinfo and then replace with the extension you want.
Not the answer you’re looking for? Browse other questions tagged php temporary-files or ask your own question.
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.9.17.40238
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Create temporary file and auto removed
Thanks so much for any reply
7 Answers 7
PHP has a function for that name tmpfile. It creates a temporary file and returns a resource. The resource can be used like any other resource.
E.g. the example from the manual:
The file is automatically removed when closed (using fclose()), or when the script ends. You can use any file functions on the resource. You can find these here. Hope this will help you?
Another solution would be to create the file in the regular way and use a cronjob to regular check if a session is expired. The expiration date and other session data could be stored in a database. Use the script to query that data and determine if a session is expired. If so, remove it physically from the disk. Make sure to run the script once an hour or so (depending on your timeout).
So we have one or more files available for download. Creating a temporary file for each download requests is not a good idea. Creating a symlink() for each file instead is a much better idea. This will save loads of disk space and keep down the server load.
Naming the symlink after the user’s session is a decent idea. A better idea is to generate a random symlink name & associate with the session, so the script can handle multiple downloads per session. You can use session_set_save_handler() (link) and register a custom read function that checks for expired sessions and removes symlinks when the session has expired.
Ok, so we have the following requirements so far
Let’s see. This is not working code, but it should work along these lines:
And that’s it. No database required. This should cover requirements 1-3. You cannot control speed with PHP, but if you dont destroy the session after sending a file you could write a counter to the session and limit the number of files the user will be sent during a session.
I wholeheartedly agree that this could be solved much more elegantly than with this monkeyform hack, but as proof-of-concept, it should be sufficient.
I’d suggest you not to copy the file in the first place. I’d do the following: when user requests the file, you generate a random unique string to give him the link this way: dl.php?k=hd8DcjCjdCkk123 then put this string to a database, storing his IP address, maybe session and the time you’ve generated the link. Then another user request that file, make sure all the stuff (hash, ip and so on) matches and the link is not expired (e.g. not more that N hours have passed since the generation) and if everything is OK, use PHP to pipe the file. Set a cron job to look through the DB and remove the expired entries. What do you think?
Creates a temporary file with a unique name in read-write (w+) mode and returns a file handle. The file is automatically removed when closed (using fclose()), or when the script ends.
Maybe it’s to late for answering but I’m try to share on feature googlize!
if you use CPanel there is a short and quick way for blocking external request on your hosted files which name is: HotLink.
you can Enable HotLinks on you Cpanel and be sure nobody can has request o your file from another hosting or use your files as a download reference.
Making it downloadable as a file. To do so, I would get the contents from the protected file, or if it is stored in a database table, fetch it and simply output it. Using php headers, I would, give it a desired name, extension, specify it’s type, and finally force the browser to download the output as a solid file.
Как создать временный файл на PHP, когда функция tmpfile() не подходит
Когда PHP-программисту необходимо создать временный файл, он в мануале находит функцию tmpfile() и после изучения примеров начинает думать, как её лучше применить. Так было и со мной, когда мне потребовалось выгрузить данные сразу во временный файл, а не работать с ними через переменную. Но с файлом, созданным таким образом, в дальнейшем неудобно работать в силу того, что tmpfile() возвращает дескриптор, а не ссылку на локальный файл. Давайте немного углубимся в анатомию временного файла и рассмотрим подводные камни, с которыми мне пришлось столкнуться.
Временные файлы в PHP нужны, например, для загрузки большого количества данных из сети или выгрузки данных из БД. Сохранять мега- или гигабайты дынных в переменной не самая лучшая идея, поскольку потребление памяти интерпретатором и сервером ограничено. Лучшим вариантом является сохранение данных на диске и удаление их по результату обработки. Функция tmpfile() именно так и работает, но в PHP существуют и другие нативные способы, с помощью которых можно организовать работу с временными данными:
Получаем URI временного файла
Какие значения возвращает stream_get_meta_data() хорошо описано в документации, но нас больше интересует абсолютный путь к файлу, связанный с потоком. Его можно извлечь по ключу uri из полученного массива:
Получив абсолютный путь к временному файлу вы можете пользоваться привычными интерфейсами для работы с данными через файл: symfony/filesystem, symfony/http-foundation, thephpleague/flysystem или нативными PHP-функциями.
Проблемы функции tmpfile()
К сожалению, сохранить временный файл через rename() не получится, т. к. tmpfile() для Windows накладывает блокирующий режим и файл будет всё ещё занят другим процессом. В UNIX-системах такой проблемы нет, здесь временный файл можно удалять ещё до закрытия ресурса. Другими словами, для Windows вызов rename() до fclose() приведёт к ошибке:
Создание временного файла
Полагаться на __destruct() плохая идея, т. к. в языках с автоматическим управлением памятью, нельзя быть уверенным на 100% в том, когда он выполнится. Деструктор не должен оставлять объект в нестабильном состоянии, поэтому в PHP обработчики уничтожения и освобождения объекта отделены друг от друга. Обработчик освобождения вызывается, когда движок полностью уверен, что объект больше нигде не применяется.
Для гарантированного удаления временного файла мы можем зарегистрировать свою функцию, которая выполнится в любом случае после завершения скрипта. Делается это с помощью register_shutdown_function() в конструкторе нашего класса:
Мы вынесли обработчик удаления временного файла в статическое замыкание, чтобы отвязать все ссылки от объекта и сохранить вызов __destruct до register_shutdown_function :
Класс TmpFile избегает ситуации, когда на него по умолчанию открыт дескриптор. Теперь можно использовать rename() вместо copy() и не бояться, когда при сохранении временных данных в другой файл на диске хранится две копии до завершения скрипта. Главное не держать открытый дескриптор, чтобы rename() наверняка отработала в Windows.
Также мы получили возможность типизировать временный файл и декларировать его тип через конструктор или методы классов, чтобы быть увереным, что приходит временный файл, а не строка, т. к. в PHP нет валидации на тип resource в сигнатурах.
Пример с загрузкой файлов
Ниже реальный юзкейс, в котором функция tmpfile() не подходит в силу уничтожения временного файла после закрытия ресурса или невозможности использовать rename() для перемещения файла. В этом случае нужно было вернуть временный файл в объекте File из пакета symfony/http-foundation в код, у которого строгая зависимость от этого класса File. Код ниже загружает файл как временный, валидирует его и сохраняет на диске:
Бизнес-логика предполагала валидацию файла на другом уровне и здесь важно было позаботиться об удалении файла в самом начале его пути, если проверка будет провалена. С помощью функции register_shutdown_function() мы можем гарантировать, что временный файл будет удалён, когда скрипт завершится. В сниппете ниже приведён пример того, как был использован класс TmpFile вместо tmpfile() :
В коде создаётся объект временного файла, открывается на него дескриптор и через cURL выкачивается файл по ссылке. Обработка HTTP-статусов и другие параметры cURL в этом сниппете не указаны. В итоге мы закрываем все дескрипторы и отправляем временный файл в нужной обёртке. Решить этот юзкейс через функцию tmpfile() было бы невозможно.
Временный файл в CLI и try-finally
В вебе запросы пользователей живут относительно недолго, но в CLI скрипты могут выполняться бесконечно и гарантировать выполнение функции register_shutdown_function() мы не можем. Скрипт может быть убит на системном уровне или выполнятся так долго, что все временные файлы останутся лежать без их финальной обработки. В консоле лучшим способом удаления временных файлов является использование конструкции try-finally :
Чем класс TmpFile отличается от tmpfile()
На основе идей из этой статьи, я написал менеджер для управления временными файлами, который доступен в репозитории denisyukphp/tmpfile-manager. Менеджер умеет много полезного: 1) настраивать путь к папке с временными файлами; 2) задавать префикс временным файлам; 3) закрывать отрытые ресурсы на временные файлы; 4) автоматически или вручную очищать временные файлы; 5) запускать свой сборщик мусора.
Вы можете использовать TmpFile независимо от менеджера, но TmpFileManager позволяет получить больше контроля над временными файлами и может гарантировать их удаление.
tempnam
(PHP 4, PHP 5, PHP 7, PHP 8)
tempnam — Создаёт файл с уникальным именем
Описание
Создаёт файл с уникальным именем в определённой директории с правами 0600. Если эта директория не существует или недоступна для записи, tempnam() может создать файл во временной директории системы и вернуть полный путь к этому файлу, включая его имя.
Список параметров
Директория, где будет создан временный файл.
Префикс имени генерируемого файла.
Замечание: Используются только первые 63 символа префикса. Windows по-прежнему использует только первые три символа префикса.
Возвращаемые значения
Возвращает имя нового временного файла (вместе с путём) или false в случае неудачи.
Примеры
Пример #1 Пример использования функции tempnam()
// здесь мы чего-нибудь делаем
Примечания
Смотрите также
User Contributed Notes 23 notes
Warning: tempnam() [function.tempnam]: open_basedir restriction in effect.
File() is not within the allowed path(s): (/var/www/vhosts/example.com/httpdocs:/tmp)
What works is this:
= tempnam ( sys_get_temp_dir (), ‘FOO’ ); // good
?>
Please note that this function might throw a notice in PHP 7.1.0 and above. This was a bugfix: https://bugs.php.net/bug.php?id=69489
You can place an address operator (@) to sillence the notice:
?>
Or you could try to set the «upload_tmp_dir» setting in your php.ini to the temporary folder path of your system. Not sure, if the last one prevents the notices.
tempnam() function does not support custom stream wrappers registered by stream_register_wrapper().
For example if you’ll try to use tempnam() on Windows platform, PHP will try to generate unique filename in %TMP% folder (usually: C:\WINDOWS\Temp) without any warning or notice.
?>
ouputs:
———————
PHP 5.2.13
node exists: 1
node is writable: 1
node is dir: 1
tempnam in dir: C:\Windows\Temp\tmp1D03.tmp
If you want to create temporary file, you have to create your own function (which will probably use opendir() and fopen($filename, «x») functions)
Be careful with you forward and back slashes. Innocent looking code like this.
i.e. /Program Files/Apache Group/Apache2/htdocs/sasdap/uploads/\TMP3D.tmp
Must. remember. to. use. backslashes.
I want to guarantee that the file will be created in the specified directory or else the function should return FALSE, I have a simple function that works, but I am unsure if its a potential security issue.
This function returns just the name of the temporary file in the specified directory, or FALSE.
>Under UNIX (where you can rename onto an extant file and so I used link), you will have to remove both the link and the link’s target.
The «newtempnam» recipe provided below (posted by «tempnam» on » 23-Jul-2003 08:56″) has at least one race condition. The while loop checks to make sure that the file in question doesn’t exist, and then goes and creates the file. In between the existence test and the fopen() call there is an opportunity for an attacker to create the file in question.
This is a classic race-condition, and while it seems difficult to exploit there are a number of well-known attacks against this kind of sloppy file creation.
The atomic primitives necessary to implement secure file creation are not available at the language level in PHP. This further underscores the need for PHP-language developers to rely on the language’s security primitives (including tempnam() and tempfile()) instead of rolling their own.
Creating a temporary file with a specific extension is a common requirement on dynamic websites. Largely this need arises from Microsoft browsers that identify a downloaded file’s mimetype based on the file’s extension.
No single PHP function creates a temporary filename with a specific extension, and, as has been shown, there are race conditions involved unless you use the PHP atomic primitives.
I use only primitives below and exploit OS dependent behaviour to securely create a file with a specific postfix, prefix, and directory. Enjoy.
return false ;
>
?>
The isWindows function is mostly left as an exercise for the reader. A starting point is below: