所以即時通訊使圖片上傳功能的網站,即時通訊存儲圖像名稱的數據庫。我截取了我的mac,並想上傳這張照片「Screen shot 2011-02-18 at 6.52.20 PM.png」。那麼,這不是一個很好的名字來存儲在MySQL!人們如何以通過上傳的每張照片都有唯一名稱的方式重新命名照片?另外,如何確保在重命名照片時最終保留文件擴展名。什麼是處理上傳圖片名稱的「傳統」方式?
回答
我會下降延伸,否則的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'])
。我會說它應該是獨一無二的。
散列圖像名稱。可能是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];
}
?>
你可以使用一個像表一樣:
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
。
「刪除擴展名」是什麼意思?你是說你只會將散列值存儲在mysql中,而不是散列+文件擴展名? – Ben 2011-03-23 01:34:14
我會將用戶在數據庫中給予您的所有內容存儲起來,但將文件本身存儲在服務器上,並且使用唯一的名稱而不帶擴展名。 – alex 2011-03-23 01:36:03
但如果它的圖像,並且如果你刪除擴展名,你怎麼知道圖像是一個JPEG,GIF或PNG訪問時? – Ben 2011-03-23 01:44:39