2010-04-25 90 views
0

我正在嘗試將用戶提交的文章添加到我的網站(僅限管理員)。每篇文章都有一個選項可以上傳3張圖片。我的數據庫建立這樣如何在php中命名上傳的文件以防止被覆蓋?

文章

id 
user_id 
title 
body 
date_added 
last_edited 

照片

id (auto_increment) 
article_id 

首先,我保存的文章在數據庫中,然後我上傳照片(臨時)然後創建一個新的照片在數據庫中記錄保存article_id。然後,我將上傳的照片重命名爲與照片記錄的主鍵相同,併成爲png。

$filename = $photo->id . '.png';

我想這是防止文件的形式被覆蓋的好方法。這對我來說似乎有缺陷。有關如何保存我的記錄和照片的任何建議?

謝謝

+0

什麼問題? – Ben 2010-04-25 03:32:25

+0

*(參考)* http://de3.php.net/manual/en/function.uniqid.php – Gordon 2010-04-25 10:06:41

回答

1

僅僅使用數據庫主鍵來命名文件沒有任何問題。

我看到的唯一真正的缺點是,你最終用相當無用的文件名。有人可能會抱怨道,更多的描述性名稱將有助於搜索引擎排名等。

另一個答案指出,重命名文件以.png結尾不會使其成爲png。如果您想實際轉換圖像格式,您可能需要查看PHP的內置GD庫(或查看ImageMagick)。

+0

那裏有真話。 – Ben 2010-04-25 03:53:22

1

哈希它們。

我已經使用PHP的MD5函數在圖片上傳到圖庫時對圖片進行哈希處理。它有兩個主要的好處:不同的圖像不會相互覆蓋,相同的圖像。這意味着每個獨特的圖片將有一個獨特的名字。接受上傳,散列存儲的數據,建立文件名(hash.extension),檢查現有文件。如果存在,請刪除臨時文件並僅使用現有副本。否則,重命名臨時文件並保留它。您可能需要跟蹤鏈接到每個文件的內容(以確保您不會刪除其他地方使用的文件),但它可以在重複文件上節省大量空間,並且是獲取唯一名稱的簡單方法。

而且,你不能只重命名使用PNG擴展名的文件,你需要將它們轉換成PNG格式或保存原來的擴展名。使用錯誤的擴展名可能會在某些地方,某些瀏覽器中導致問題,而且通常不正確。

+0

這絕對值得考慮。在某些情況下,可能會方便地擁有同一文件的多個副本(以便一個用戶的刪除不會全部刪除),而其他情況下,由實際文件內容定義唯一性的空間節省特性可能非常有用。 – 2010-04-25 03:47:00

1

對於它的價值,這裏是我的文件上傳類的方法包括我,以確保我不會覆蓋現有文件。我傳遞上傳文件名稱($ _FILES [$ img_field] [「name」])和目錄以將文件保存爲參數,因此這仍然是常規方法。

private function unique_file_upload($filename, $dir) { 
     $filename = preg_replace("/[^.\w]/",'_',$filename); 
     $filename = preg_replace("/__+/",'_',$filename); 
     preg_match("/^(.*)\.(\w{2,4})$/",$filename,$f); 
     if (file_exists($dir . $filename)) { 
      $num = 1; 
      while (file_exists($dir . $filename)) { 
       preg_match("/^(.*)\.(\w{2,4})$/",$filename,$f); 
       preg_match("/(\d+)$/",$f[1],$n); 
       if ($n[1]) { 
        $x = $n[1]; 
        $num = $n[1] + 1; 
        $num .= '.'; 
        $filename = preg_replace("/$x\./",$num,$filename); 
       } 
       else { 
        $filename = $f[1] . $num . '.' . $f[2]; 
       } 
      } 
     } 
     return $filename; 
    } 
1

如果圖像使用自動遞增主鍵作爲名稱,那麼絕對不可能有兩個具有相同名稱的圖像。

散列或做任何額外的事情來確保名稱中的唯一性毫無價值。更重要的是,這意味着在數據庫中添加一個額外的圖像名稱字段。

圖像可能被覆蓋的唯一方法是,如果您重置數據庫自動增加計數器,並且爲此,您需要刪除表上的以前的記錄,否則計數器將再次由DBMS重新計算爲最高ID記錄在桌子上。

換句話說,使用你的算法,你將不會有兩個同名的圖像。

0

正確的方法是將文件與關聯記錄的主鍵ID一起存儲。要處理「但這只是一個無用的號碼」,你可以將原始文件名存儲在「照片」表中。如果你允許多種圖像類型,你也可以存儲MIME類型。

然後,您使用一個簡單的腳本從數據庫中檢索文件的名稱,並使用Content-disposition: attachment; filename=$filename標題將其提供給客戶端。這樣,即使您的服務器上的文件名是(比如說)「3527」,客戶端也會看到「originalimagefilename.jpg」或其他任何內容的下載。