[英]How to prevent PHP files from being downloaded? And what are some ways someone can download them?
[英]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.