2009-12-10 70 views
3

我目前正在使用Zend框架,並有一個上傳文件的形式。經過身份驗證的用戶可以上傳文件,該文件將存儲在應用程序的目錄中,以及存儲在數據庫中的位置。這樣它可以顯示爲可以下載的文件。PHP:存儲文件位置...如果被覆蓋,會怎麼樣?

<a href="/upload-location/filename.pdf">Download</a> 

但我注意到的是,具有相同名稱的文件將覆蓋上傳目錄中的文件。沒有錯誤消息,文件名也不會增加。所以我認爲文件必須被覆蓋(或從未上傳)。

上傳,移動或存儲這些文件時應該注意哪些最佳做法?我應該總是重命名文件,以便文件名始終是唯一的嗎?

回答

9

通常,我們不會以用戶給出的名稱存儲文件,而是使用我們的名稱(即我們的應用程序) chosse。

例如,如果用戶上傳my_file.pdf,我們將:

  • 存儲在DB一條線,包含:
    • id;一個自動增量,主鍵 - 「123」,例如
    • 用戶給出的名稱;所以當有人試圖下載文件的內容類型
    • 時,我們可以發送正確的名稱; application/pdf或類似的東西,例如。
    • 「我們的」名稱:file-123例如
  • 當有文件的請求與id=123,我們知道哪些物理文件將被取回('file-' . $id)和發送。
  • ,我們可以設置一些頭髮送給正確的「邏輯」名稱給瀏覽器,使用我們存儲在數據庫的名稱,「另存爲」對話框
  • 相同的內容類型,順便說一句

通過這種方式,我們確保:

  • 沒有文件有任何「錯誤」的名字,因爲我們選擇它的人,而不是客戶端
  • 沒有overwritting:如我們的文件名包括我們表的主鍵,這些文件名是唯一
+0

很好的答案,謝謝! – Andrew 2009-12-10 20:01:30

+0

@Andrew:不客氣:-)玩得開心! – 2009-12-10 20:08:22

+0

甜美完美的感謝帕斯卡! +1 – 2013-10-11 11:16:25

0

是的,你需要拿出一個辦法來唯一名字。我見過各種不同的策略的這種從上原始文件名的哈希基地,數據庫記錄的pk和上傳時間戳,某種類型的段塞,再基於數據庫記錄varous領域的附着或相關記錄。

1

帕斯卡·馬丁的答案繼續:

如果使用的ID作爲名字你也可以拿出一個目錄命名策略。我不再從文件系統中獲得/somedir/part1ofID/part2OfID,而是從/somedir/theWholeID中獲取/somedir/part1ofID/part2OfID,但是它可以讓您選擇將ID分割爲路徑和文件名的方式,從同一目錄中存儲多少個文件。

下一件好事是您用於實際輸出文件給用戶的腳本可以選擇用戶是否有權查看該文件。這當然需要將文件存儲在默認情況下每個人都無法讀取的地方。您可能還想看看this other question。不完全相關,但很好意識到。

+1

如果您要「繼續」或添加到某人的回答中,請對他們的回答使用評論,而不是將其作爲回答發佈。主要是因爲如果有很多答案,你的文章將不會被添加到你的文章旁邊。 – TravisO 2009-12-10 20:29:45

+0

是的,那也是我的想法。我只是覺得評論框有點限制了添加較長的答案。你建議我做什麼,刪除我的答案,並將其添加爲評論,或添加更多的上下文到我的答案? – 2009-12-10 21:21:25