【问题标题】:Validate that a file is a picture in PHP验证文件是 PHP 中的图片
【发布时间】:2010-12-07 13:23:21
【问题描述】:

如果文件上传到服务器,有没有办法使用 PHP 来确保它实际上是一张图片,而不仅仅是一个扩展名为 .jpg 或 .gif 的文件?

【问题讨论】:

    标签: php image security validation


    【解决方案1】:

    使用(部分)GD 库。

    PHP: GD - Manual

    array getimagesize ( string $filename [, array &$imageinfo ] )
    

    如果没有图像,则数组的第一个元素将为 0。 PHP: getimagesize

    如果您没有安装 GD(大多数时候您会安装),您可以将文件头读取为Shane mentioned

    编辑: 实际上,正如 Neal 在 cmets 中指出的那样,GD 库甚至不需要使用此功能。所以使用它。

    【讨论】:

    • @Neal - 实际上,我没有!我不知道。感谢您指出了这一点。答案已编辑。我不是第一次接受 RTFM 了
    • 没问题 ^_^ 乐于助人!
    • 使用exif_imagetype更好,更快
    • 官方文档说“不要使用 getimagesize() 来检查给定文件是否为有效图像”
    • 这个函数运行太慢了。你有更好的主意吗?
    【解决方案2】:

    检查文件是否为图像的最佳方法

    function is_image($path)
    {
        $a = getimagesize($path);
        $image_type = $a[2];
    
        if(in_array($image_type , array(IMAGETYPE_GIF , IMAGETYPE_JPEG ,IMAGETYPE_PNG , IMAGETYPE_BMP)))
        {
            return true;
        }
        return false;
    }
    

    更多:http://www.binarytides.com/php-check-if-file-is-an-image/

    【讨论】:

    • Caution: 不要使用 getimagesize() 来检查给定文件是否为有效图像。
    【解决方案3】:

    最有效的方法是查看文件的开始字节并测试“幻数”文件说明符。 Here is a list of magic numbers.

    【讨论】:

    • 这将比启动 GD 更有效,但我认为打开二进制文件等...对于大多数人来说有点过头了。
    • 如果这是真的 - 它非常令人失望。这里的大多数人不是有 CS 学位吗?
    • 我不知道……但我从 7 岁起就开始编写代码。令人惊讶的是,许多人可以在不知道自己应该做什么的情况下获得学位。我是根据经验说话的,因为我确实拥有土木工程学位,而且我认识很多刚刚滑过的“滑块”。学位没有任何意义。证明你可以做某事。
    • 哦,我相信这个网站的大量用户没有CS学位。大多数人最终都从 Google 来到这里,他们试图了解他们正在学习的语言。
    • 同意 - 我亲眼看到了。然而 - 想到那些从事编程工作的人(我认为其中许多人都是这样)仍然令人失望,并且二进制打开已经超出了他们的头脑。
    【解决方案4】:

    标题检查不足以检查图像文件的有效性。 PHP 文档明确表示您不应使用getimagesize 来检查给定文件是否为有效图像。见https://www.php.net/manual/en/function.getimagesize.php

    我使用以下函数来验证图像文件:

        /**
         * Returns TRUE if $path is a valid Image File
         *
         * @param string $path
         * @return bool
         */
        public static function isImage(string $path)
        {
    
            if (!is_readable($path)) {
                return false;
            }
    
            // see https://www.php.net/manual/en/function.exif-imagetype.php for Constants
            // adjust this array to your needs
            $supported = [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG];
    
            $type = exif_imagetype($path);
    
            // $type can be valid, but not "supported"
            if (!in_array($type, $supported)) {
                return false;
            }
    
            // check the image content, header check is not enough
            $image = false;
            switch ($type) {
                case IMAGETYPE_GIF:
                    $image = @imagecreatefromgif($path);
                    break;
                case IMAGETYPE_PNG:
                    $image = @imagecreatefrompng($path);
                    break;
                case IMAGETYPE_JPEG:
                    $image = @imagecreatefromjpeg($path);
                    break;
            }
            return (!!$image);
        }
    

    【讨论】:

      【解决方案5】:

      郑重声明:现在在 2013 年+,我们可以:

      最大。兼容性(如果您没有 GD 库)。
      使用始终可用的mime-content-type ((PHP 4 >= 4.3.0, PHP 5))

      $type = mime_content_type($filename);
      if (strstr($type, 'image/'))
      {
          echo 'is image';
      }
      

      【讨论】:

      • 仍然适用于 php 7
      猜你喜欢
      • 1970-01-01
      • 2017-03-26
      • 2018-07-19
      • 2011-11-25
      • 2014-06-16
      • 1970-01-01
      • 2013-12-20
      • 2021-09-26
      • 2012-03-05
      相关资源
      最近更新 更多