php 如何检查上传的文件是否是没有 mime 类型的图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6484307/
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
How to check if an uploaded file is an image without mime type?
提问by Click Upvote
I'd like to check if an uploaded file is an image file (e.g png, jpg, jpeg, gif, bmp) or another file. The problem is that I'm using Uploadify to upload the files, which changes the mime type and gives a 'text/octal' or something as the mime type, no matter which file type you upload.
我想检查上传的文件是图像文件(例如 png、jpg、jpeg、gif、bmp)还是其他文件。问题是我正在使用 Uploadify 上传文件,这会更改 mime 类型并提供“文本/八进制”或其他内容作为 mime 类型,无论您上传哪种文件类型。
Is there a way to check if the uploaded file is an image apart from checking the file extension using PHP?
除了使用PHP检查文件扩展名之外,有没有办法检查上传的文件是否是图像?
回答by Alain Tiemblo
My thought about the subject is simple: all uploaded images are evil.
我对这个主题的想法很简单:所有上传的图片都是邪恶的。
And not only because they can contain malicious codes, but particularly because of meta-tags. I'm aware about crawlers that browse the web to find some protected images using their hidden meta-tags, and then play with their copyright. Perhaps a bit paranoid, but as user-uploaded images are out of control over copyright issues, I take it seriousely into account.
不仅因为它们可能包含恶意代码,而且特别是因为元标记。我知道有一些爬虫会浏览网页以使用其隐藏的元标记查找一些受保护的图像,然后利用其版权进行游戏。也许有点偏执,但由于用户上传的图像不受版权问题的控制,我认真考虑了这一点。
To get rid of those issues, I systematically convert all uploaded images to png using gd. This have a lot of advantages: image is clean from eventual malicious codes and meta tags, I only have one format for all uploaded images, I can adjust the image size to fit with my standard, and... I immediately know if the image is valid or not!If the image can't be opened for conversion (using imagecreatefromstringwhich doesn't care about image format), then I consider the image as invalid.
为了摆脱这些问题,我使用 gd 系统地将所有上传的图像转换为 png。这有很多优点:图像没有最终的恶意代码和元标记,我所有上传的图像只有一种格式,我可以调整图像大小以适合我的标准,并且......我立即知道图像是否有效与否!如果无法打开图像进行转换(使用不关心图像格式的imagecreatefromstring),那么我认为该图像无效。
A simple implementation could look like this:
一个简单的实现可能如下所示:
function imageUploaded($source, $target)
{
// check for image size (see @DaveRandom's comment)
$size = getimagesize($source);
if ($size === false) {
throw new Exception("{$source}: Invalid image.");
}
if ($size[0] > 2000 || $size[1] > 2000) {
throw new Exception("{$source}: Too large.");
}
// loads it and convert it to png
$sourceImg = @imagecreatefromstring(@file_get_contents($source));
if ($sourceImg === false) {
throw new Exception("{$source}: Invalid image.");
}
$width = imagesx($sourceImg);
$height = imagesy($sourceImg);
$targetImg = imagecreatetruecolor($width, $height);
imagecopy($targetImg, $sourceImg, 0, 0, 0, 0, $width, $height);
imagedestroy($sourceImg);
imagepng($targetImg, $target);
imagedestroy($targetImg);
}
To test it:
要测试它:
header('Content-type: image/png');
imageUploaded('http://www.dogsdata.com/wp-content/uploads/2012/03/Companion-Yellow-dog.jpg', 'php://output');
This does not exactly answer your question as this is the same kind of hack than the accepted answer, but I give you my reasons to use it, at least :-)
这并不能完全回答你的问题,因为这与接受的答案是同一种黑客,但我给你我使用它的理由,至少:-)
回答by Scott C Wilson
You could use getimagesize()
which returns zeros for size on non-images.
您可以使用getimagesize()
which 为非图像的大小返回零。
回答by Jens A. Koch
If Uploadify really changes the mime type - i would consider it a bug. It doesn't make sense at all, because that blocks developers from working with mime-type based functions in PHP:
如果 Uploadify 真的改变了 mime 类型 - 我会认为这是一个错误。这完全没有意义,因为这会阻止开发人员在 PHP 中使用基于 MIME 类型的函数:
This is a little helper function which returns the mime-type based on the first 6 bytes of a file.
这是一个小辅助函数,它根据文件的前 6 个字节返回 MIME 类型。
/**
* Returns the image mime-type based on the first 6 bytes of a file
* It defaults to "application/octet-stream".
* It returns false, if problem with file or empty file.
*
* @param string $file
* @return string Mime-Type
*/
function isImage($file)
{
$fh = fopen($file,'rb');
if ($fh) {
$bytes = fread($fh, 6); // read 6 bytes
fclose($fh); // close file
if ($bytes === false) { // bytes there?
return false;
}
// ok, bytes there, lets compare....
if (substr($bytes,0,3) == "\xff\xd8\xff") {
return 'image/jpeg';
}
if ($bytes == "\x89PNG\x0d\x0a") {
return 'image/png';
}
if ($bytes == "GIF87a" or $bytes == "GIF89a") {
return 'image/gif';
}
return 'application/octet-stream';
}
return false;
}
回答by rcode
You can verify the image type by checking for magic numbers at the beginning of the file.
您可以通过检查文件开头的幻数来验证图像类型。
For example: Every JPEG file begins with a "FF D8 FF E0"block.
例如:每个 JPEG 文件都以“FF D8 FF E0”块开头。
Here is more info on magic numbers
这是有关幻数的更多信息
回答by kaore
Try using exif_imagetypeto retrieve the actual type of the image. If the file is too small it will throw an error and if it can't find it it will return false
尝试使用exif_imagetype来检索图像的实际类型。如果文件太小,它会抛出一个错误,如果它找不到它,它会返回 false
回答by Kibbee
You can check the first few bytes of the file for the magic numberto figure out the image format.
您可以检查文件的前几个字节的幻数以找出图像格式。
回答by Jeffrey Jenkinson
Is it not possible to interrogate the file with finfo_file?
不能用finfo_file查询文件吗?
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $filename); //should contain mime-type
finfo_close($finfo);
This answer is untested but based on this forum discussionon the Uploadify forums.
此答案未经测试,但基于Uploadify 论坛上的此论坛讨论。
I would also point out that finfo should "try to guess the content type and encoding of a file by looking for certain magic byte sequences at specific positions within the file"so in my mind this should still work even though Uploadify has specified the wrong mime type.
我还要指出 finfo 应该“尝试通过在文件中的特定位置查找某些魔术字节序列来猜测文件的内容类型和编码”,因此在我看来,即使 Uploadify 指定了错误的 mime,这仍然应该有效类型。