2011-03-23 92 views
1

所以即時通訊使圖片上傳功能的網站,即時通訊存儲圖像名稱的數據庫。我截取了我的mac,並想上傳這張照片「Screen shot 2011-02-18 at 6.52.20 PM.png」。那麼,這不是一個很好的名字來存儲在MySQL!人們如何以通過上傳的每張照片都有唯一名稱的方式重新命名照片?另外,如何確保在重命名照片時最終保留文件擴展名。什麼是處理上傳圖片名稱的「傳統」方式?

回答

5

我會下降延伸,否則的Apache(或等同物)如果被請求將運行a1e99398da6cf1faa3f9a196382f1fadc7bb32fb7.php(其可能包含惡意PHP )。我也會把它上傳到docroot上面。

如果需要,使文檔根目錄上面的圖片訪問,你可以存儲通過圖像功能跑到一個安全副本或一些PHP與header('Content-Type: image/jpeg')例如和readfile()include因爲我可以嵌入服務它PHP在一個GIF文件中)。

此外,pathinfo($path, PATHINFO_EXTENSION)是獲得一個擴展的最佳途徑。

確保您已將原始文件名和其他元數據的引用存儲在數據庫中。

function getUniqueName($originalFilename) { 
    return sha1(microtime() . $_SERVER['REMOTE_ADDR'] . $originalFilename); 
} 

這可以生成重複的唯一方法是如果一個具有相同IP的用戶在一微秒內多次上傳相同的文件名。

或者,您可以使用PHP在您上載圖像時指定的basename($_FILES['upload']['tmp_name'])。我會說它應該是獨一無二的。

+0

「刪除擴展名」是什麼意思?你是說你只會將散列值存儲在mysql中,而不是散列+文件擴展名? – Ben 2011-03-23 01:34:14

+0

我會將用戶在數據庫中給予您的所有內容存儲起來,但將文件本身存儲在服務器上,並且使用唯一的名稱而不帶擴展名。 – alex 2011-03-23 01:36:03

+0

但如果它的圖像,並且如果你刪除擴展名,你怎麼知道圖像是一個JPEG,GIF或PNG訪問時? – Ben 2011-03-23 01:44:39

0

散列圖像名稱。可能是md5,sha1甚至是unix時間戳。

下面是一個(未測試)實施例與一個隨機數(10到99)

<?php 
function generate_unique_name($file_name) 
{ 
    $splitted = split(".", $file_name); 
    return time() . rand(10,99) . "." . $splitted[count($splitted)-1]; 
} 
?> 
+0

dont md5和sha1分別輸出32和40個字符?這是一個圖像名稱的字符... – Ben 2011-03-23 01:12:24

+0

至少它會是唯一的。另外,你可以擴展unix時間戳,所以如果兩個人同時提交,你不會得到兩個這個名字的圖片。 – Ghpst 2011-03-23 01:14:45

+0

我見過很多unix時間戳+隨機數。你也可以使用類似crc32的東西。 – 2011-03-23 01:15:22

0

你可以使用一個像表一樣:

id: int 
filename: varchar 
hash: varchar 
format: enum('jpeg', 'png') 

哈希可以像sha1_file($uploaded_file)和用於確保重複的圖像上載。 (因此,如果需要,您可以在圖像表中使用相同的散列值創建多個條目。)該id很有用,因此您可以將整數外鍵鏈接返回到圖像表。

下一頁存儲圖像在任:

/image/$id.$format 

/image/$hash.$format 

通過哈希第二種格式將確保你不會重複的圖像數據。如果你正在處理大量的圖片,你可能想要做的事,如:

/image/a/b/c/abcdef12345.jpg 

在您使用文件夾的多層存儲影像。許多文件系統因單個目錄中的文件過多而變慢。

現在你可以鏈接到這些文件直接,或建立一個網址,如:

/image/$id/$filename 

例如:

/image/12347/foo.jpg 

foo.jpg來自任何用戶上傳。它實際上被忽略,因爲你通過id查找。但是,如果用戶選擇下載圖像,它會使圖像有一個很好的名稱。 (您可以選擇驗證圖像文件名匹配後,您查找id)

上述路徑可以通過Apache的MultiView或ModRewrite轉換爲image.php。然後,您可以使用readfile()或使用X-SendFile(更好的性能,但不總是可用)將文件發送給用戶。

請注意,如果您沒有X-SendFile並且不想通過PHP處理內容,則可以使用RewriteRule將/image/$hash/foo.jpg轉換爲/image/a/b/c/$hash.jpg