我需要将一些文件转换为PDF,然后将它们附加到电子邮件中。我正在使用Pear Mail作为它的电子邮件方面,这很好(主要是 - 仍在解决一些问题)但作为其中的一部分,我需要创建临时文件。现在我可以使用tempnam()函数,但听起来它在文件系统上创建了一个文件,这不是我想要的。
我只想在临时文件系统中使用一个名称(使用sys_get_temp_dir()),该名称不会与运行同一用户的同一脚本的其他人多次冲突。
建议?
答案 0 :(得分:138)
我过去曾使用uniqid()来生成唯一的文件名,但实际上并没有创建文件。
$filename = uniqid(rand(), true) . '.pdf';
第一个参数可以是你想要的任何东西,但是我在这里使用了rand()使它更加随机。使用set前缀,可以进一步避免与系统中的其他临时文件冲突。
$filename = uniqid('MyApp', true) . '.pdf';
从那里,您只需创建文件。如果所有其他方法都失败了,那就把它放在while循环中并继续生成它,直到你得到一个有效的方式。
while (true) {
$filename = uniqid('MyApp', true) . '.pdf';
if (!file_exists(sys_get_temp_dir() . $filename)) break;
}
答案 1 :(得分:23)
说真的,使用tempnam()。是的,这会创建文件,但这是一个非常有意的安全措施,旨在防止系统上的其他进程“窃取”您的文件名并导致您的进程覆盖您不想要的文件。
即,请考虑以下顺序:
PHP的tempnam()实际上调用了系统的mkstemp(用于Linux ...替换其他操作系统的“最佳实践”功能),这样就完成了这样的过程:
现在,您可以自己所有这些事情,但为什么,当“正确的功能”执行创建安全临时文件所需的所有内容时,为什么,这几乎总是涉及创建一个空文件你。
例外:
答案 2 :(得分:3)
您可以使用部分日期和时间来创建唯一的文件名,这样在多次调用时不会重复。
答案 3 :(得分:2)
考虑使用uuid作为文件名。考虑uniqid函数。 http://php.net/uniqid
答案 4 :(得分:1)
另一种基于@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
更快)。
更多信息:
答案 5 :(得分:0)
我建议你使用PHP函数 http://www.php.net/tempnam
$file=tempnam('tmpdownload', 'Ergebnis_'.date(Y.m.d).'_').'.pdf';
echo $file;
/var/www/html/tmpdownload/Ergebnis_20071004_Xbn6PY.pdf
<?php
$temp = tmpfile();
fwrite($temp, "writing to tempfile");
fseek($temp, 0);
echo fread($temp, 1024);
fclose($temp); // this removes the file
?>
答案 6 :(得分:0)
最好使用带有用户ID的Unix时间戳。
$filename='file_'.time().'_'.$id.'.jepg';
答案 7 :(得分:0)
我的想法是使用递归函数来查看文件名是否存在,如果存在,则迭代到下一个整数:
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);
答案 8 :(得分:0)
更新2020
hash_file('md5', $file_pathname)
这样,您可以防止重复。
答案 9 :(得分:-1)
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;
}