我需要將一些文件轉換爲PDF,然後將它們附加到電子郵件。我使用Pear Mail作爲它的電子郵件端,這很好(主要 - 仍然解決一些問題),但作爲這一部分,我需要創建臨時文件。現在我可以使用tempnam()函數,但它聽起來像在文件系統上創建了一個文件,這不是我想要的。PHP中的唯一和臨時文件名?
我只是想在臨時文件系統中使用一個名稱(使用sys_get_temp_dir()),該名稱不會與運行同一用戶的同一腳本的其他人重複多次調用該腳本。
對此提出建議?
我需要將一些文件轉換爲PDF,然後將它們附加到電子郵件。我使用Pear Mail作爲它的電子郵件端,這很好(主要 - 仍然解決一些問題),但作爲這一部分,我需要創建臨時文件。現在我可以使用tempnam()函數,但它聽起來像在文件系統上創建了一個文件,這不是我想要的。PHP中的唯一和臨時文件名?
我只是想在臨時文件系統中使用一個名稱(使用sys_get_temp_dir()),該名稱不會與運行同一用戶的同一腳本的其他人重複多次調用該腳本。
對此提出建議?
我以前用uniqid()生成一個唯一的文件名,但實際上並沒有創建文件。
$filename = uniqid(rand(), true) . '.pdf';
第一個參數可以是任何你想要的,但我在這裏使用rand()使它更加隨機。使用設置的前綴,可以進一步避免與系統中其他臨時文件的衝突。
$filename = uniqid('MyApp', true) . '.pdf';
從那裏,你只是創建文件。如果一切都失敗了,把它放在一個while循環中,並繼續生成它,直到你得到一個工作。
while (true) {
$filename = uniqid('MyApp', true) . '.pdf';
if (!file_exists(sys_get_temp_dir() . $filename)) break;
}
考慮使用uuid作爲文件名。考慮uniqid函數。 http://php.net/uniqid
您可以使用日期和時間的一部分來創建唯一的文件名,這樣在多次調用時不會重複。
我建議你使用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
?>
function gen_filename($dir) {
if ([email protected]_dir($dir)) {
@mkdir($dir, 0777, true);
}
$filename = uniqid('MyApp.', true).".pdf";
if (@is_file($dir."/".$filename)) {
return $this->gen_filename($dir);
}
return $filename;
}
嚴重的是,使用的tempnam()。是的,這會創建文件,但這是一種非常有意的安全措施,旨在防止系統上的其他進程「竊取」文件名並導致進程覆蓋不需要的文件。
即,考慮這個序列:
PHP的tempnam()實際上在引擎蓋下調用系統的mkstemp(這是Linux的... ...替代其他操作系統的「最佳實踐」功能),它經過這樣一個過程:
,你可以做所有的那些東西的事情,但爲什麼當「適當功能」確實的需要的,以創建安全的臨時文件,而且幾乎總是涉及爲您創造一個空文件的一切。
例外:
更好,如果您使用unix時間戳與用戶ID。
$filename='file_'.time().'_'.$id.'.jepg';
基於@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
)快。
更多信息:
我的想法是使用遞歸函數來查看如果文件名存在,並且如果存在,則重複下一個整數:
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);
+1 while循環! – RobertPitt 2011-03-10 21:05:33
我喜歡在uniquid上使用第一個參數的隨機數,但是我使用mt_rand()來代替,因爲它的速度。這對於使用while循環的地方會有幫助,並且有很多文件。 – 2011-05-29 16:55:12
我不知道在那裏添加一個rand()是否會使得它有更多*隨機 - 可能是uniqid和rand()都被系統時間所接種。 – 2013-03-18 23:16:29