如何检查上传的文件是否是没有mime类型的图像?
image-processing
php
4
0

我想检查上传的文件是图像文件(例如png,jpg,jpeg,gif,bmp)还是其他文件。问题是,无论您上传哪种文件类型,我都使用Uploadify上传文件,这会更改mime类型并给出“文本/八进制”或类似的mime类型。

除了使用PHP检查文件扩展名之外,是否有其他方法可以检查上传的文件是否为图像?

参考资料:
Stack Overflow
收藏
评论
共 7 个回答
高赞 时间 活跃

您可以使用getimagesize()来返回非图像大小的零。

收藏
评论

我对这个问题的想法很简单:所有上传的图片都是邪恶的。

不仅是因为它们可能包含恶意代码,而且还因为元标记。我知道爬网程序会浏览网络以使用其隐藏的元标记查找一些受保护的图像,然后使用其版权进行播放。也许有点偏执,但是由于用户上传的图像对版权问题已失去控制,因此我认真考虑了这一点。

为了摆脱这些问题,我使用gd系统地将所有上传的图片转换为png。这有很多优点:图像可以清除最终的恶意代码和meta标签,我只有一种格式可用于所有上传的图像,我可以调整图像大小以符合我的标准,并且... 我立即知道该图像是否是否有效!如果无法打开图像进行转换(使用不关心图像格式的imagecreatefromstring ),那么我认为该图像无效。

一个简单的实现可能看起来像这样:

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

要测试它:

header('Content-type: image/png');
imageUploaded('http://www.dogsdata.com/wp-content/uploads/2012/03/Companion-Yellow-dog.jpg', 'php://output');

这并不能完全回答您的问题,因为这与接受的答案是同一种hack,但是我给您我使用它的理由,至少:-)

收藏
评论

尝试使用exif_imagetype检索图像的实际类型。如果文件太小,它将引发错误;如果找不到文件,则将返回false

收藏
评论

无法用finfo_file询问文件吗?

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $filename); //should contain mime-type
finfo_close($finfo);

该答案未经测试,但基于Uploadify论坛上的该论坛讨论

我还要指出,finfo应该“通过在文件中的特定位置查找某些魔术字节序列来尝试猜测文件的内容类型和编码”,因此在我看来,即使Uploadify指定了错误的mime,这仍然应该有效类型。

收藏
评论

如果Uploadify确实改变了mime类型-我会认为这是一个错误。这根本没有任何意义,因为这会阻止开发人员在PHP中使用基于mime类型的函数:

这是一个小辅助函数,该函数根据文件的前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;
}
收藏
评论

您可以通过检查文件开头的幻数来验证图像类型。

例如:每个JPEG文件都以“ FF D8 FF E0”块开头。

这是有关魔术数字的更多信息

收藏
评论

您可以检查文件的前几个字节中的幻数以找出图像格式。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号