如何在PHP中检查上传的文件类型

时间:2011-07-19 23:09:33

标签: php file-upload

我使用此代码检查图像类型,

$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"){...

有任何意见吗?

9 个答案:

答案 0 :(得分:78)

永远不要使用$_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非常棒,如果您的服务器支持它们。

答案 1 :(得分:9)

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

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

答案 2 :(得分:4)

当然你可以检查它是否是带有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 );

答案 3 :(得分:2)

我认为最好的方法是先使用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()最终尝试将文件作为图像打开 - 如果成功 - 我们有一个图像。

答案 4 :(得分:1)

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

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

基本上我使用mime_content_type()来获得类似" image / jpg"然后通过" /"将其爆炸并检查数组的第一个元素,看它是否显示" image"。

我希望它有效!

答案 5 :(得分:0)

在PHP 5.5中,我使用此函数获取文件类型并检查是否为image:

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/

答案 6 :(得分:0)

最后一行关闭。您可以使用: if (mime_content_type($_FILES['fupload']['tmp_name']) == "image/gif"){...

在我目前正在处理的情况下,我的$_FILES..['type']报告自身为“ text / csv”,而mime_content_type()finfo()(由他人建议)均报告为“ text / csv”平原。”。正如@deceze指出的那样,$_FILES..['type']仅对了解客户认为文件的类型有用。

答案 7 :(得分:-2)

您可以尝试

$file_extension = explode('.',$file['name']);
$file_extension = strtolower(end($file_extension));
$accepted_formate = array('jpeg','jpg','png');
if(in_array($file_extension,$accepted_formate)) {           
  echo "This is jpeg/jpg/png file";
} else {
  echo $file_extension.' This is file not allowed !!';
}

答案 8 :(得分:-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