Как стать автором
Обновить

Комментарии 16

Вообще-то, в *nix-подобных системах вы спокойно можете удалить файл, сразу после получения его дескриптора от функции fopen(). И продолжать работать с его дескриптором — по окончании работы вашей программы _любым_ способом — временного файла ни диске не останется.
я так и не понял, зачем вам понадобился путь до временного файла?

сама идея, что среда предоставляет вам дескриптор некого файла, размещенного фиг знает где, исключительно для задач временного хранения, может через 5 лет будет норма для временных файлов в системе делать специальное хранилище (пониженная надежность например) а ваше приложение будет ожидать путь до файла, а оно даже монтироваться в файловое дерево не будет.
Мне нужно было передать имя временного файла вместе с классом File из Symfony HttpFoundation в объект, в котором чётко прописана зависимость от класса File в конструкторе. Переписать этот объект я не мог. С моей стороны, бизнес-логика предполагала создание временного файла с определёнными данными, а с другой — валидацию и перемещение, где не предусмотрено удаление файла в случае отрицательной проверки. Два слоя приложения разрабатывались разными программистами. Временный файл наполнялся пользовательскими данными.
вот это уже реальный кейс.
а на практике этот путь хоть где то использовался в дальнейшем, или можно было пустую строку туда отправить?

Да, использовался. Временный файл перемещался из временной папки куда-то на диск для хранения с помощью метода move() или удалялся, если валидацию не проходил. Пустую строку никак нельзя было отправить.

НЛО прилетело и опубликовало эту надпись здесь

Несмотря на то, что UploadedFile наследует File, задача была другая. UploadedFile предполагает загрузку файлов из $_FILES всё таки.

НЛО прилетело и опубликовало эту надпись здесь

UploadedFile в любом случае не подойдёт, так как реализация метода move() отличается от такого же из класса File. UploadedFile строго для $_FILES, посмотрите исходники. Статья не об этом, временный файл можно передать куда угодно и с чем угодно, тут всё зависит от конкретной задачи. Я использовал File, т. к. была явная зависимость в дочернем классе.

Вы неправильно готовите временные файлы.
Опишите правильный рецепт!

Если нужен был ооп почему не пользовали SplTempFileObject, у которого есть помимо всего еще и getPathname, который и возвращает путь к файлу?

SplTempFileObject является обёрткой для php://temp и php://memory. Метод getPathname() не вернёт URI, а укажет на тот же поток (php://temp). Это всё тот же fopen(), только через объект. SplTempFileObject имеет баги от класса SplFileInfo, который наследует через SplFileObject, т. к. getRealPath() показывает не тот результат, который ожидается.


Здесь даже не ООП был нужен, а механизм, который может создать c URI временный файл и передать в какой-то класс имя файла. В классе File из Symfony HttpFoundation есть метод move(), который не сможет переместить временный файл, созданный tmpfile(), т. к. тот заблокирован на время работы с потоком. По большому счёту это всё из-за трансферинга временного файла между объектами, которые не работают с потоками, а только с именами файлов.

Благодарю за разъяснения.
действительно есть такой баг и уже висит 3 года. проголосовал за него, он всё еще есть в 7.0.х версии.

Не часто работаю непосредственно с файлами, потому полезно было узнать.
НЛО прилетело и опубликовало эту надпись здесь

Функция register_shutdown_function() регистрирует функцию, которая будет выполнена по завершению скрипта. Свой класс я покрыт тестами. Всё отработает как задумано.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации