2011-07-19 65 views
23

我用这个代码来检查的图像类型检查上传的文件类型,如何在PHP

$f_type=$_FILES['fupload']['type']; 

if ($f_type== "image/gif" OR $f_type== "image/png" OR $f_type== "image/jpeg" OR $f_type== "image/JPEG" OR $f_type== "image/PNG" OR $f_type== "image/GIF") 
{ 
    $error=False; 
} 
else 
{ 
    $error=True; 
} 

但一些用户抱怨在上载任何类型的图像,他们得到一个错误,而另一些人不要”没有任何错误!

我在想,如果这能解决问题:

if (mime_content_type($_FILES['fupload']['type']) == "image/gif"){...

有何评论?

回答

64

千万不要使用$_FILES..['type']。其中包含的信息根本没有被验证,这是用户定义的值。自己测试类型。对于图片,exif_imagetype通常是一个不错的选择:

$allowedTypes = array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF); 
$detectedType = exif_imagetype($_FILES['fupload']['tmp_name']); 
$error = !in_array($detectedType, $allowedTypes); 

另外,在finfo functions是巨大的,如果你的服务器支持他们。

+0

错误!调用未定义的函数exif_imagetype() – John

+0

我认为这个扩展没有在我的共享主机上启用:'extension = php_mbstring.dll extension = php_exif.dll' – John

+0

@John尝试http://upgradephp.berlios.de然后,它提供了一个直接替换。 – deceze

7

除了@deceze,您也可以finfo()检查MIME类型的非图像文件:

$finfo = new finfo(); 
$fileMimeType = $finfo->file($path . $filename, FILEINFO_MIME_TYPE); 
-5

警告:下面的答案实际上不检查文件类型。它只检查名称。出于实际安全目的,它是不适合

编辑:不要使用这种方法,因为它没有安全检查。我在这里留下这个答案,以便没有人通过尝试这样做像我一样的错误。


我尝试了以下内容和它的工作对我来说:

$allowed = array('gif','png' ,'jpg', 'pdf'); 
$filename = $_FILES['input_tag_name']['name']; 
$ext = pathinfo($filename, PATHINFO_EXTENSION); 
if(!in_array($ext,$allowed)) { 
    echo 'error'; 
} 

Source link

+12

**警告!这绝对没有任何检查!**它所做的只是检查扩展是否在允许的数组中。如果将'myVirus.exe'重命名为'myVirus.jpg',那么它可以通过你的函数来完成。很明显,这是**不**你想要什么... – Byson

+1

这是非常危险的....避免和从不使用它的严重文件检查事项 – ErickBest

0

在PHP 5.5我用这个函数用于获取文件类型和检查,如果图像:

function getFileType($file) { 
    return image_type_to_mime_type(exif_imagetype($file)); 
} 

// Get file type 
$file_type = getFileType('path/to/images/test.png'); 
echo $file_type; 
// Prints image/png 
// 1. All images have mime type starting with "image" 
// 2. No other non-image mime types contain string "image" in it 

然后你可以这样做:

if (strpos($filetype, 'image') !== false) { 
    // This is an image 
} 

完整的MIME类型的列表:http://www.sitepoint.com/web-foundations/mime-types-complete-list/

0

当然,你可以检查它是否与EXIF的图像,但更好的办法,我认为是FINFO这样做:

$allowed_types = array ('application/pdf', 'image/jpeg', 'image/png'); 
$fileInfo = finfo_open(FILEINFO_MIME_TYPE); 
$detected_type = finfo_file($fileInfo, $_FILES['datei']['tmp_name']); 
if (!in_array($detected_type, $allowed_types)) { 
    die ('Please upload a pdf or an image '); 
} 
finfo_close($fileInfo); 
1

最好在我看来,首先使用getimagesize(),然后是imagecreatefromstring()

$size = getimagesize($filename); 
    if ($size === false) { 
     throw new Exception("{$filename}: Invalid image."); 
    } 
    if ($size[0] > 2500 || $size[1] > 2500) { 
     throw new Exception("{$filename}: Image too large."); 
    } 

    if (!$img = @imagecreatefromstring(file_get_contents($filename))) { 
     throw new Exception("{$filename}: Invalid image content."); 
    } 

通过getimagesize()检查防止一些DoS攻击,因为我们没有从用户提供的每一个文件设法imagecreatefromstring(),要么非图像文件或文件太大。不幸的是,根据PHP docs不能依赖检查图像类型的内容。

imagecreatefromstring()终于尝试打开文件作为图像 - 如果成功 - 我们有一个图像。

0

这是一个我经常使用的简单的单行脚本。

$image = "/var/www/Core/temp/image.jpg"; 
$isImage = explode("/", mime_content_type())[0] == "image"; 

基本上我用mime_content_type()来获得类似“图像/ JPG”,然后按“/”爆炸并检查对数组的第一个元素,看看它说:“图像”。

我希望它的作品!