簡體   English   中英

如何在php中命名上傳的文件,以防止它們被覆蓋?

[英]How to name uploaded files in php to prevent them from being overwritten?

我正在嘗試將用戶提交的文章添加到我的網站(僅適用於管理員)。 每篇文章都有一個選項,可以上傳最多3張圖片。 我的數據庫是這樣建立的

用品

id
user_id
title
body
date_added
last_edited

相片

id (auto_increment)
article_id

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

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

我認為這將是防止文件格式被覆蓋的好方法。 這在我看來是有缺陷的。 關於如何保存記錄和照片有什么建議嗎?

謝謝

哈希它們。

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

另外,您不能只是將文件重命名為使用PNG擴展名,而是需要將其轉換為PNG格式或保存原始擴展名。 使用錯誤的擴展名可能會在某些地方,某些瀏覽器中引起問題,並且通常是錯誤的。

對於它的價值,這是我在文件上傳類中包含的一種方法,以確保我不會覆蓋現有文件。 我傳遞了上傳文件的名稱($ _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;
  }

僅使用數據庫主鍵來命名文件並沒有真正的錯誤。

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

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

如果圖像使用自動遞增主鍵作為名稱,則絕對不會有兩個具有相同名稱的圖像。

散列或進行任何其他操作以確保名稱的唯一性是毫無價值的。 甚至更多,這意味着在數據庫中添加了額外的圖像名稱字段。

可能會覆蓋圖像的唯一方法是,如果您重置數據庫自動增量計數器,並且要執行此操作,則需要刪除表上的先前記錄,否則DBMS將再次將計數器重新計算為該表上的最高id記錄。

換句話說,使用您的算法,就不會有兩個具有相同名稱的圖像。

正確的方法是使用相關記錄的主鍵ID存儲文件。 要處理“但它只是一個無用的數字”,您可以將原始文件名存儲在“照片”表中。 如果允許多種圖像類型,則還可以存儲mime類型。

然后,您使用一個簡單的腳本,該腳本將從數據庫中檢索文件的名稱,並通過Content-disposition: attachment; filename=$filename將其提供給客戶端Content-disposition: attachment; filename=$filename Content-disposition: attachment; filename=$filename標頭。 這樣,即使服務器上的文件名是(例如)“ 3527”,客戶端也將看到“ originalimagefilename.jpg”或其他文件的下載。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM