2010-02-25 47 views
6

使用PHP將新照片上傳到Linux服務器時,我不得不爲它們指定唯一的名稱(使用它的文件名被排除)。沒有與數據庫的交互,因此獲取唯一的ID也是不可能的。如何爲上傳的照片生成短文件名?

我想到使用DATE + TIME.jpg,但這太長了。

那麼,什麼是用PHP創建儘可能短的唯一名稱的最佳方法是什麼?

回答

8

使用tempnam()

$filename = tempnam ($dir, $prefix) 

,它創建一個在指定目錄中唯一名稱的文件。生成的文件名非常短,並且保證是唯一的。

+0

生成的文件沒有擴展名,手動添加擴展名會破壞唯一性保證。 – Farhadi 2010-02-25 12:15:58

0

如果我是你,我只希望產生一個隨機數大約是6個字符,並做好在do {} (while)循環,直到它的獨特。

0

的一個方法是使用隨機的文件名。像rand(0,99999999)+".jpg"。 碰撞的概率非常小(如果你沒有很多圖像),並且你可以很容易地通過一些怪異的機會檢查這個名字是否已經被採用並且在這種情況下得到一個新的名字。

+0

我會強烈反對這個建議:根據隨機數生成器的播種方式,您可能會以驚人的速度碰撞碰撞。 – 2010-02-25 09:31:44

2

你也可以使用相同的排序散列該URL縮短器像bit.ly使用產生他們獨特的5個字符的文件夾名稱(例如bit.ly/x3hs0)。

There's an implementation in PHP here

0

最短是不是最好的方式。我想你可以使用md5($ date + $ time)函數來獲取唯一的文件名。它會是這樣的:8d41627e46d5b8556d0d3e30ec15538e。

而且,如果你認爲會有上傳的文件大數目,你可以通過文件夾的名稱將你的目錄結構,例如,包括MD5的前兩個字母()哈希:

8d/ 
    + 8d41627e46d5b8556d0d3e30ec15538e.jpg 
    + 8d897234ed899a523c88273c009c12c2.jpg 
ce/ 
    + ce2389898ace097cc667e134abb61729.jpg 
... 
1

創建索引文件;此文件包含用於文件的最後一個ID。當一個新的文件,需要創建:

  1. 鎖定索引文件(如果您的操作系統支持)
  2. 讀取ID
  3. 添加1到ID
  4. 保存文件
  5. 解鎖文件
  6. 與ID創建一個文件

問候,
斯泰恩

+0

建議不要這樣做,因爲它會讓其他人僅通過更改數字(這可能不是您想要的)來瀏覽圖像非常容易。 – 2010-02-25 09:33:13

+0

確實;如果你不想要這個,那麼只是使用增加的數字不是一種選擇。雖然你也可以增加13例如1而不是1;或添加當前ID的第一個數字,... – 2010-02-25 09:38:50

1

好了,問題是,你想要的東西獨一無二且短。你不可能有兩個。

人類可讀的隨機數最密集的表示形式類似於base64(對於不應該在文件名中的任何字符替換有效字符)。然而,這仍然意味着文件名中每個字符只有「64」變化。

如果您想要一個簡單的文件名,只需使用遞增的數字並將其編碼爲base64(如果您希望名稱的最小長度,請將其編碼)。如果你希望它是不可猜測的,你需要一個隨機數生成器,但是你需要確保避免雙打或者最終覆蓋文件。名字越短,發生災難的機會就越高。

你可以使用你自己的base64自定義等效字符而不僅僅是該編碼提供的64個字符,但是你必須檢查你的操作系統認爲一個有效的文件名,你仍然必須確保客戶端可以正確訪問它(如果它不僅僅是一個臨時數據存儲)。最簡單的方法是創建一個字符串,讓每個你想要合法的字符都轉換成字符串,然後將該字符串的基數轉換爲字符串的長度(如果你不知道的話,可以在Google上進行基本轉換的解釋怎麼做)。這將允許更高的信息密度和更短的文件名。

3

最簡單的安全方法是使用uniqid()函數。

0

您可以使用一個隨機數和日期+時間舍姆,並檢查名稱在一段時間()循環存在:

$new_name = md5(rand(0,99999) . date('Ymd') . microtime(true)) . $extension; 
while (file_exists($path . $new_name)) 
    $new_name = md5(rand(0,99999) . date('Ymd') . microtime(true)) . $extension; 

其中$ NEW_NAME是你上傳的文件

的短名稱

$擴展是你文件的擴展名(如.jpg)

$路徑是的完整路徑該文件有目錄中保存

使用蘭特()microtime中(真) inscrease找到一個獨特的名字,第一次拍攝的機會......

1

我總是做將文件名設置爲文件本身的MD5散列 - 這樣做的副作用是避免了重複上傳佔用空間,並且可以相當容易地驗證數據完整性。

如果你希望它更短,你可以從最後開始截斷位,但你做這件事越多,你冒着文件名衝突的風險就越大,但從經驗來說,採取前八個字符通常保證提供唯一性你不要上傳太多。