Intereting Posts
избегать возврата после выхода из системы Не может получить тело ответа 401 Memcache для работы с API-интерфейсами с высоким временем ожидания – хорошая идея? Fread намного медленнее для загрузки, чем readfile «Ошибка 404 не найдена» в Magento Admin Login Page Как отфильтровать Dangerous HTML, например SO? Как создать ответ электронной почты / метод, чтобы закодировать ответ? strip_tags и htmlentities Ошибка подключения к MySQL. Не удается подключиться к серверу MySQL на «http» (4) Возврат списка цепочек и последнего сообщения каждого сообщения с использованием базы данных php и mysql Достигнут максимальный уровень гнездования функции «100», прерванный после обновления до Laravel 5.1 более короткий способ повторения переменной в php? SQLSTATE Доступ запрещен для пользователя «имя пользователя» @ «localhost» с использованием CakePhp Как пропустить JSON-массив с помощью PHP Очистить содержимое сайта С помощью безопасного входа в систему

Уникальные и временные имена файлов в PHP?

Мне нужно преобразовать некоторые файлы в PDF, а затем присоединить их к электронной почте. Я использую Pear Mail для электронной почты, и это нормально (в основном – все еще разрабатываются некоторые проблемы), но в качестве части этого мне нужно создать временные файлы. Теперь я мог бы использовать функцию tempnam (), но похоже, что он создает файл в файловой системе, чего я не хочу.

Я просто хочу имя во временной файловой системе (используя sys_get_temp_dir () ), которая не будет конфликтовать с кем-то другим, выполняющим тот же скрипт того же самого пользователя, который вызывает сценарий несколько раз.

Предложения?

Related of "Уникальные и временные имена файлов в PHP?"

Я использовал uniqid () в прошлом для создания уникального имени файла, но фактически не создавал файл.

$filename = uniqid(rand(), true) . '.pdf'; 

Первый параметр может быть любым, что вы хотите, но я использовал rand () здесь, чтобы сделать его еще более случайным. Используя префикс набора, вы можете избежать конфликтов с другими файлами temp в системе.

 $filename = uniqid('MyApp', true) . '.pdf'; 

Оттуда вы просто создаете файл. Если все остальное не удается, поместите его в цикл while и продолжайте генерировать его, пока не получите тот, который работает.

 while (true) { $filename = uniqid('MyApp', true) . '.pdf'; if (!file_exists(sys_get_temp_dir() . $filename)) break; } 

Серьезно, используйте tempnam (). Да, это создает файл, но это очень преднамеренная мера безопасности, предназначенная для предотвращения очередного процесса в вашей системе от «кражи» вашего имени файла и заставляя ваш процесс перезаписывать файлы, которые вам не нужны.

Т.е. рассмотрим эту последовательность:

  • Вы генерируете случайное имя.
  • Вы проверяете файловую систему, чтобы убедиться, что она не существует. Если это так, повторите предыдущий шаг.
  • Другой, злой процесс создает файл с тем же именем, что и жесткая ссылка на файл. Г-н Evil хочет, чтобы вы случайно перезаписали.
  • Вы открываете файл, думая, что вы создаете файл, а не открываете существующий в режиме записи, и начинаете писать.
  • Вы просто переписывали что-то важное.

PHP tempnam () на самом деле вызывает mkstemp системы под капотом (это для Linux … замените функцию «лучшей практики» для других ОС), которая проходит через такой процесс:

  • Выберите имя файла
  • Создайте файл с ограничительными разрешениями внутри каталога, который запрещает другим пользователям удалять файлы, которые он не имеет (это то, что делает липкий бит на / var / tmp и / tmp)
  • Подтверждает, что созданный файл все еще имеет ограничительные разрешения.
  • Если какой-либо из вышеперечисленных ошибок не удается, повторите попытку с другим именем.
  • Возвращает созданное имя файла.

Теперь вы можете делать все эти вещи самостоятельно, но почему, когда «правильная функция» делает все, что требуется для создания защищенных временных файлов, и это почти всегда предполагает создание для вас пустого файла.

Исключения:

  • Вы создаете временный файл в каталоге, в который может быть создан только ваш процесс.
  • Создайте случайно созданный временный каталог , который только ваш процесс может создавать / удалять файлы.

Вы можете использовать часть даты и времени, чтобы создать уникальное имя файла, таким образом, он не дублируется при вызове более одного раза.

Рассмотрите возможность использования uuid для имени файла. Рассмотрим уницидную функцию. http://php.net/uniqid

Другая альтернатива, основанная на ответе @Lusid с отказоустойчивостью максимального времени выполнения:

 //////////// Max exectution time of 10 seconds. $maxExecTime = time() + 10; $isUnique = false; while (time() !== $maxExecTime) { //////////// Unique file name $uniqueFileName = uniqid(mt_rand(), true) . '.pdf'; if (!file_exists(sys_get_temp_dir() . $uniqueFileName)){ $isUnique = true; break; } } if($isUnique){ //////////// Save your file with your unique name }else{ //////////// Time limit was exceeded without finding a unique name } 

Заметка:

Я предпочитаю использовать mt_rand вместо rand потому что первая функция использует Mersenne Twister algorithm и быстрее второго ( LCG ).


Больше информации:

Лучше, если вы используете временную метку unix с идентификатором пользователя.

$filename='file_'.time().'_'.$id.'.jepg';

Моя идея состоит в том, чтобы использовать рекурсивную функцию, чтобы увидеть, существует ли имя файла, и если да, то итерация к следующему целому числу:

 function check_revision($filename, $rev){ $new_filename = $filename."-".$rev.".csv"; if(file_exists($new_filename)){ $new_filename = check_revision($filename, $rev++); } return $new_filename; } $revision = 1; $filename = "whatever"; $filename = check_revision($filename, $revision); 

Я рекомендую вам использовать функцию PHP http://www.php.net/tempnam

 $file=tempnam('tmpdownload', 'Ergebnis_'.date(Ymd).'_').'.pdf'; echo $file; /var/www/html/tmpdownload/Ergebnis_20071004_Xbn6PY.pdf 

Или http://www.php.net/tmpfile

 <?php $temp = tmpfile(); fwrite($temp, "writing to tempfile"); fseek($temp, 0); echo fread($temp, 1024); fclose($temp); // this removes the file ?> 
 function gen_filename($dir) { if (!@is_dir($dir)) { @mkdir($dir, 0777, true); } $filename = uniqid('MyApp.', true).".pdf"; if (@is_file($dir."/".$filename)) { return $this->gen_filename($dir); } return $filename; }