2009-08-08 56 views
5

我有以下代碼:檢查圖片文件類型和大小

$filecheck = basename($_FILES['imagefile']['name']); 
    $ext = substr($filecheck, strrpos($filecheck, '.') + 1); 
    if (($ext == "jpg" || $ext == "gif" || $ext == "png") && ($_FILES["imagefile"]["type"] == "image/jpeg" || $_FILES["imagefile"]["type"] == "image/gif" || $_FILES["imagefile"]["type"] == "image/png") && 
    ($_FILES["imagefile"]["size"] < 2120000)){ 
} else { 
echo "F2"; 
die(); 
} 

我需要做的是檢查,如果上傳的文件是JPG/GIF/PNG什麼和它的不足2 megs大小。

如果其大於2兆,或不正確的文件類型,我需要返回/回波F2(用於API錯誤代碼)。

當我使用上面的代碼來處理一個70K JPG文件,它返回F2。

SUBNOTE 圖片即時上傳的擴展名爲.JPG。情況可能是一個因素?如果是這樣,我該如何適應?

+1

要回答你的子注:''$ ext = strtolower(substr($ filecheck,strrpos($ filecheck,'。')+ 1));' – jimyi 2009-08-08 21:30:15

回答

22

請注意,您可能不希望依賴於文件擴展名來確定文件類型,這將是相當容易的人。成與.png擴展例如上載的可執行文件。一個MIME類型也可以輕易地由惡意客戶端被僞造通過爲圖像。依託該信息是一個安全風險

PHP Documentation:
文件的mime類型,如果瀏覽器提供這個信息。一個例子就是「image/gif」。此MIME類型然而,不檢查了PHP側,因此不要把它視爲理所當然值。

嘗試加載圖像與gdgetimagesize()),以確保它們實際上是有效的圖像(不只是隨機文件與圖像文件的頭假裝... finfo_file依靠這些頭)。

if($_FILES["imagefile"]["size"] >= 2120000) { 
    echo "F2"; 
    die(); 
} else { 
    $imageData = @getimagesize($_FILES["imagefile"]["tmp_name"]); 

    if($imageData === FALSE || !($imageData[2] == IMAGETYPE_GIF || $imageData[2] == IMAGETYPE_JPEG || $imageData[2] == IMAGETYPE_PNG)) { 
     echo "F2"; 
     die(); 
    } 
} 

如果你真的必須使用擴展驗證,如果該文件是一個圖像,用strtolower()把擴展成小寫。

$filecheck = basename($_FILES['imagefile']['name']); 
$ext = strtolower(substr($filecheck, strrpos($filecheck, '.') + 1)); 

if (!(($ext == "jpg" || $ext == "gif" || $ext == "png") && ($_FILES["imagefile"]["type"] == "image/jpeg" || $_FILES["imagefile"]["type"] == "image/gif" || $_FILES["imagefile"]["type"] == "image/png") && 
    ($_FILES["imagefile"]["size"] < 2120000))){ 
    echo "F2"; 
    die(); 
} 
+0

額外的,形而上學的+1爲一個很好的答案。 – 2009-11-17 15:38:33

5

筆記本都圖像IM上載有.JPG的延伸。情況可能是一個因素?如果是這樣,我該如何適應?

是的,這就是問題所在。你應該用strtolower()添加到此行:

$ext = substr($filecheck, strrpos($filecheck, '.') + 1); 

,如:

$分機=用strtolower(SUBSTR($ filecheck,strrpos($ filecheck)+ 1) '');

這將解決您的問題,目前。但從技術上講,你不應該擔心文件擴展名,你應該只需要檢查MIME類型

+0

確實是MIME類型。該文件也可以命名爲.jpeg。 – 2009-08-08 21:32:38

+0

依賴該信息**是安全風險**。請閱讀我的答案。 – 2009-08-08 22:20:08

5

比較如$ext == "jpg"只檢查$ext是完全「jpg」。

你可能想在$分機使用strtolower做這些比較之前,應對「.JPG」的局面。


如果你正在使用PHP < = 5.2,你可能需要使用mime_content_type檢查,而不是依靠$_FILES['imagefile']['name']和/或$_FILES["imagefile"]["type"],這兩者都是由客戶端發送的內容類型的文件, - 並且可以如此僞造。

如果你正在使用PHP> = 5.3,你可能要考慮新的擴展fileinfo,這是,你已經在使用​​finfo_file功能


對於文件的大小;沒關係,我想,但你只知道它時,該文件已被上傳 - 不過,有檢查之類的話上傳之前沒有真正的方法,我怕......


你也許能找到一些JS代碼做延伸的第一前檢查前的文件上傳 - 但你仍然必須檢查在服務器端,因爲任何事情的客戶端本質上是不安全的。

不知道你可以做有關文件的大小相同,但...

有些瀏覽器可能支持一個隱藏字段名爲MAX_FILE_SIZE(請參閱文檔有關file upload);但不知道它是真的支持(從來沒有見過它用,實際上,這樣可能不是:-()


一點題外話,你可能會想配置upload_max_filesize,因此它允許上傳至少大你想要什麼(默認情況下,一般設置爲2MB,所以應該已經爲你OK)

2

PHP是一種服務器端腳本語言,如果圖片是在客戶端,你無法通過PHP 以前上傳檢查它們的大小。

+0

非常好的一點 - 可以使用一些javascript來檢查文件大小,並拒絕,而*文件類型*可以通過@Andrew Moore的答案在內部檢查腳本 – warren 2009-09-28 11:01:09

2

你需要兩樣東西:

讓您的分機支票不區分大小寫:

if($strtolower($ext == "jpg")){ 
    // do your stuff 
} 

檢查文件,實際上包含的圖像。一個簡單的方法來做到這一點的FileInfo:

$finfo = finfo_open(FILEINFO_MIME_TYPE); 
echo finfo_file($finfo, $filename); 
$finfo_close($finfo); 

檢查的另一種方式,如果一個文件實際上是一個圖像加載像GD圖像庫。如果您的文件可以成功加載,它是一個圖像。

請記住,jpeg圖像可以有.jpg.jpeg擴展名。

3

注意到,爲Internet Explorer, 他們提交JPEG文件的MIME類型圖像/ PJPEG - 這是從其他瀏覽器不同。

這裏有一個簡單的功能,讓您的MIME類型與文件擴展名:

function mime2ext($mime){ // mime is like image/jpeg 
    $m = explode('/',$mime); 
    $mime = $m[count($m)-1]; // get the second part of the mime type 
    switch($mime){ 
     case 'jpg': 
     case 'jpeg': 
     case 'pjpeg': 
      return 'jpg'; 
      break; 
     case 'png': 
      return 'png'; 
      break; 
     case 'gif': 
      return 'gif'; 
      break; 
    } 
    return ''; 
} 
3

文件大小是相當明顯的,但什麼人在上面做檢查,這是一個正確的格式是有點低效,並且「不安全」。

這是我做的:

if($_FILES["userPicture"]["error"] == 0) { 
// File was uploaded ok, so it's ok to proceed with the filetype check. 
    $uploaded_type = exif_imagetype($_FILES["userPicture"]["tmp_name"]); 
    // What we have now is a number representing our file type. 

    switch($uploaded_type) { 
     case "1": 
      $uploaded_type = "gif"; 
     break; 
     case "2": 
      $uploaded_type = "jpg"; 
     break; 
     case "3": 
      $uploaded_type = "png"; 
     break; 
    } 
} 

更多信息的;
http://www.php.net/manual/en/function.exif-imagetype.php

編輯:這有「在每個瀏覽器」工作的優勢,因爲它不依賴於文件名,或任何用戶提供的,除了文件數組值「錯誤」,它告訴我們,有沒有真的是一個錯誤。