php 在php中上传文件之前检查图片文件类型和大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1249943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 01:43:51  来源:igfitidea点击:

Check picture file type and size before file upload in php

php

提问by mrpatg

I have the following code:

我有以下代码:

$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();
}

What i need to do is check if the uploaded file is a jpg/gif/png and that its less than 2 megs in size.

我需要做的是检查上传的文件是否为 jpg/gif/png 并且其大小小于 2 兆。

If its larger than 2 megs, or not the right file type, i need to return/echo F2 (error code for api).

如果它大于 2 兆字节,或者不是正确的文件类型,我需要返回/回显 F2(api 的错误代码)。

When i use the code above to process a 70k jpg file, it returns F2.

当我使用上面的代码处理 70k jpg 文件时,它返回 F2。

SUBNOTEthe picture im uploading has an extension of .JPG. Could case be a factor? If so, how do i accommodate for that?

SUBNOTE我上传的图片有.JPG 的扩展名。案件可能是一个因素吗?如果是这样,我该如何适应?

回答by Andrew Moore

Note that you might not want to rely on file extensions to determine file type. It would be rather easy for someone to upload an executable file with a .pngextension for example. A mime-type can also easily be forged by a malicious client to pass as an image. Relying on that information is a security risk.

请注意,您可能不想依赖文件扩展名来确定文件类型。.png例如,某人上传带有扩展名的可执行文件会很容易。恶意客户端也可以轻松伪造 mime 类型以作为图像传递。依赖该信息存在安全风险

PHP Documentation:
The mime type of the file, if the browser provided this information. An example would be "image/gif". This mime type is however not checked on the PHP side and therefore don't take its value for granted.

PHP 文档文件
的 MIME 类型(如果浏览器提供了此信息)。一个例子是“图像/gif”。然而,这种 mime 类型不会在 PHP 端检查,因此不要认为它的值是理所当然的

Try loading the images with gd(getimagesize()) to make sure they are actually valid images (and not just random files pretended with the header of an image file... finfo_filerelies on those headers).

尝试使用gd( getimagesize())加载图像以确保它们实际上是有效图像(而不仅仅是用图像文件头伪装的随机文件......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();
    }
}


If you really must use the extension to verify if the file is an image, use strtolower()to put the extension into lowercase.

如果您确实必须使用扩展名来验证文件是否为图像,请使用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();
}

回答by Mark

SUBNOTE the picture im uploading has an extension of .JPG. Could case be a factor? If so, how do i accommodate for that?

SUBNOTE 我上传的图片有.JPG 的扩展名。案件可能是一个因素吗?如果是这样,我该如何适应?

Yes, that is the problem. You should be add strtolower() to this line:

是的,这就是问题所在。您应该将 strtolower() 添加到这一行:

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

like:

喜欢:

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

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

That will fix your currently issue. But technically, you shouldn't worry about file extensions, you should really only need to check the MIME type

这将解决您当前的问题。但从技术上讲,你不应该担心文件扩展名,你应该只需要检查 MIME 类型

回答by Pascal MARTIN

The comparisons like $ext == "jpg"only check that the $extis exactly "jpg".

类似的比较$ext == "jpg"只检查$ext是否完全是“jpg”。

You might want to use strtoloweron $ext before doing those comparisons, to deal with the ".JPG" situation.

在进行这些比较之前,您可能希望在 $ext 上使用strtolower来处理“.JPG”情况。


If you are using PHP <= 5.2, you might want to use mime_content_typeto check the content-type of the files, instead of relying on $_FILES['imagefile']['name']and/or $_FILES["imagefile"]["type"], which are both sent by the client -- and can, as such, be faked.


如果您使用的是 PHP <= 5.2,您可能希望使用mime_content_type来检查文件的内容类型,而不是依赖$_FILES['imagefile']['name']和/或$_FILES["imagefile"]["type"],它们都是由客户端发送的——因此可以被伪造.

If you are using PHP >= 5.3, you might want to consider the new extension fileinfo, and it's finfo_filefunction

如果您使用的是 PHP >= 5.3,您可能需要考虑新的扩展名fileinfo,它的finfo_file功能


For the size of the file, you are already using $_FILES["imagefile"]["size"]; that's OK, I guess, but you will only know it when the file has been uploaded -- still, there is no real way of checking that kind of thing before upload, I'm afraid...


对于文件的大小,您已经在使用$_FILES["imagefile"]["size"]; 没关系,我想,但你只有在文件上传后才会知道——不过,在上传之前没有真正的方法来检查这种事情,恐怕......


you might be able to find some JS code to do a first pre-check of extension before the file is uploaded -- but you'll still have to check on the server side, as anything done client-side is inherently not secure.


您可能可以找到一些 JS 代码在文件上传之前对扩展名进行第一次预检查 - 但您仍然必须在服务器端进行检查,因为客户端所做的任何事情本质上都是不安全的。

Not sure you could do the same about the file's size, though...

不确定你可以对文件的大小做同样的事情,但......

Some browsers might support a hidden field called MAX_FILE_SIZE(see the documentation about file upload) ; but not sure it is really supported (never seen it used, actually ; so probably isn't :-( )

某些浏览器可能支持一个名为MAX_FILE_SIZE(请参阅有关文件上传的文档)的隐藏字段;但不确定它是否真的受支持(实际上从未见过它使用过;所以可能不是:-()


As a sidenote, you will probably want to configure upload_max_filesize, so it allows upload at least as big as what you want (by default, it is generally set to 2MB ; so should already be OK for you)


作为旁注,您可能需要配置upload_max_filesize,因此它允许上传至少与您想要的一样大(默认情况下,它通常设置为 2MB ;所以应该已经可以了)

回答by mauris

take note that for Internet Explorer, they submit JPEG file's mime type as image/pjpeg- which is different from other browsers.

请注意,对于 Internet Explorer,它们将 JPEG 文件的 mime 类型提交为image/pjpeg- 这与其他浏览器不同。

Here's a simple function to get your mime type against the file extension:

这是一个简单的函数,可以根据文件扩展名获取 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 '';
}

回答by grimman

File size is fairly obvious, but what people are doing above to check that it's the right format is somewhat inefficient, and "unsafe".

文件大小是相当明显的,但是人们在上面所做的检查其格式是否正确的操作有些低效,而且“不安全”。

Here's what I do:

这是我所做的:

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;
    }
}

More info at;
http://www.php.net/manual/en/function.exif-imagetype.php

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

Edit: This has the advantage of working "in every browser" because it doesn't rely on the filename, or anything user supplied, except the files array value "error" which tells us there wasn't really an error.

编辑:这具有“在每个浏览器中”工作的优势,因为它不依赖于文件名或用户提供的任何内容,除了文件数组值“error”,它告诉我们没有真正的错误。

回答by Ahmet Kak?c?

Php is a server side scripting language and if the pictures are at client side, you can't check their size via php beforeupload.

Php 是一种服务器端脚本语言,如果图片在客户端,则上传无法通过 php 检查其大小。

回答by Scharrels

You need two things:

你需要两件事:

Make your extension check case insensitive:

使您的扩展检查不区分大小写:

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

Check if the file actually contains an image. An easy way to do this is fileinfo:

检查文件是否确实包含图像。一个简单的方法是文件信息:

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

An alternative way of checking if a file is really an image is loading in an image library like gd. If your file can successfully be loaded, it is an image.

检查文件是否真的是图像的另一种方法是加载到像 gd 这样的图像库中。如果您的文件可以成功加载,则它是一个图像。

Keep in mind that jpeg images can have either the .jpgor the .jpegextension.

请记住,jpeg 图像可以有.jpg.jpeg扩展名。