Мне нужно преобразовать некоторые файлы в PDF, а затем присоединить их к электронной почте. Я использую Pear Mail для электронной почты, и это нормально (в основном – все еще разрабатываются некоторые проблемы), но в качестве части этого мне нужно создать временные файлы. Теперь я мог бы использовать функцию tempnam (), но похоже, что он создает файл в файловой системе, чего я не хочу.
Я просто хочу имя во временной файловой системе (используя sys_get_temp_dir () ), которая не будет конфликтовать с кем-то другим, выполняющим тот же скрипт того же самого пользователя, который вызывает сценарий несколько раз.
Предложения?
Я использовал 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 (). Да, это создает файл, но это очень преднамеренная мера безопасности, предназначенная для предотвращения очередного процесса в вашей системе от «кражи» вашего имени файла и заставляя ваш процесс перезаписывать файлы, которые вам не нужны.
Т.е. рассмотрим эту последовательность:
PHP tempnam () на самом деле вызывает mkstemp системы под капотом (это для Linux … замените функцию «лучшей практики» для других ОС), которая проходит через такой процесс:
Теперь вы можете делать все эти вещи самостоятельно, но почему, когда «правильная функция» делает все, что требуется для создания защищенных временных файлов, и это почти всегда предполагает создание для вас пустого файла.
Исключения:
Вы можете использовать часть даты и времени, чтобы создать уникальное имя файла, таким образом, он не дублируется при вызове более одного раза.
Рассмотрите возможность использования 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; }