2009-12-08 78 views
1

我有一個「困境」,不知道什麼是商業最佳實踐。什麼是驗證文件名的業務最佳實踐?

我正在使用Uploadify上傳圖片。現在我需要在保存文件之前驗證文件名。

我已經看過不同的解決方案,但不能找到一個好的解決方案。

這裏是我的標準:

  • 文件名必須全部使用小寫
  • 文件名只能包含charaters [A-Z0-9_-]
  • 我必須能夠重命名文件

如果文件名是my.file(name).jpeg,你會怎麼辦?

我可以在'。'上分解文件名。並保存擴展名,然後內爆再次獲取文件名。但不知道這是否是最好的解決辦法。

我有以下功能有點幫助:

function getExts($filename) 
{ 
    $exts = explode("[/\\.]", $filename) ; 
    $n = count($exts)-1; 
    $exts = $exts[$n]; 
    return $exts; 
} 

function validFilename($filename) 
{ 
    $filename = str_replace(" ", "_", $filename); 
    $pattern = "/[^[a-z0-9_-]/"; 
    return preg_replace($pattern, "", strtolower($filename)); 
} 

更新1
我recieving通過$ _FILES文件。這給了我下面的數據:

  • $ _FILES [ 「文件」] [ 「名稱」] - 被上傳文件
  • $ _FILES名[ 「文件」] [ 「型」] - 類型上傳文件的大小
  • $ _FILES [「file」] [「size」] - 上傳文件的大小(以字節爲單位)
  • $ _FILES [「file」] [「tmp_name」] - 臨時副本的名稱存儲在服務器上的文件
  • $ _FILES [「file」] [「error」] - 文件上傳產生的錯誤代碼

UPDATE 2
我剛剛發現了一些東西。我可以使用getimagesize這將返回一個由7個元素組成的數組。其中一個元素[2]是IMAGETYPE_XXX。

所以我嘗試使用此代碼:

function getExts2($filename) 
{ 
    list(,,$type) = getimagesize($filename); 
    return $type; 
} 

但它只返回2號...

(我也嘗試使用exif_imagetype,但只得到PHP錯誤:調用未定義功能。)

+0

'getimagesize'返回的類型可以通過'image_type_to_extension'函數轉換爲文件擴展名:http://us2.php.net/function.image_type_to_extension – 2009-12-08 23:51:58

+0

@Ben:請參閱我對使用getimagesize的評論。 – Steven 2009-12-09 09:51:44

回答

4

檢查文件名以正則表達式。使用有關mimetype的信息。使用md5名稱將文件保存在服務器上。將真實文件名存儲在數據庫

+0

使用md5保存文件很好。是的,我已經在DB中保存了文件名。但我是使用正則表達式的蝨子。 – Steven 2009-12-08 23:16:04

+0

好的,但你想檢查文件名與正則表達式? Mimetype的方式不好? – hsz 2009-12-09 00:06:43

+0

+1用'加密'文件名與md5 – TheHippo 2009-12-09 00:22:45

0

我假設您正在驗證文件名以備將來用作下載文件名。

從技術角度來看,雖然保存文件名會​​很好,但從技術角度來看,您的方法聽起來很合理。

如果你關心的網址是什麼樣子,並可能針對在未來的國際觀衆,一定要轉換要麼以變音符號的基本字符或將它們轉換。德語用戶(變音符號A○ÜSS)所期望的轉換:

Ä = ae 
Ö = oe 
Ü = ue 

而北歐人似乎用得放心

Ä => a 
Ö => o 
Ø => o 

等。

再就是各種重音符號的E中的...

刪除那些完全導致了看起來真的 BD和樂strng在bwsr地址BR網址。

3

pathinfo()可以讓你的文件名和擴展名。但是,我會警告你,不能依賴通過檢查文件的文件名來測試文件的擴展名。你會想使用一個函數來實際檢查文件的二進制內容。 finfo_file()可以做到這一點。噢,並且在用戶提供的文件路徑上使用basename()以防止路徑穿越攻擊,絕不會感到痛苦。

+0

如果你不知道擴展名,使用basename()會很困難。而且,你說,使用pathinfo不是最好的方法。最安全的是閱讀acutal二進制文件。 – Steven 2009-12-08 23:17:49

0

這應該做你想要的一切:

$filename = preg_replace('/[^[a-z0-9_-]/', '', str_replace(' ', '_', strtolower(pathinfo($filename, PATHINFO_FILENAME)))) . pathinfo($filename, PATHINFO_EXTENSION); 

而作爲佩卡解釋它,如果你想替換所有重讀你可以使用下面的函數文件名:

function Unaccent($string) 
{ 
    return preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')); 
} 
+0

用[A-Z0-9_-]問題,是還擴展之前移除點 – Steven 2009-12-08 23:19:14

+0

@Steven(?):你至少嘗試過嗎?訣竅在於使用pathinfo($ filename,PATHINFO_FILENAME)和pathinfo($ filename,PATHINFO_EXTENSION),它的工作方式與您想要的一樣。 – 2009-12-09 00:18:07

0

我不認爲你應該「驗證」文件名,如果它不是你想要的格式,你應該「修復」它。爲什麼拒絕一個文件只是因爲有人不喜歡命名他們的文件,或者有一些不尋常的人物呢?另外,如果您使用的是圖片,則可以使用getimagesize來確保其實際上是上傳的圖片(如果圖片不是圖片,則會失敗)。

+0

通過驗證,我的意思是檢查文件名。沒有文件將被拒絕,但我會刪除不需要的字符。 – Steven 2009-12-09 09:43:23