【问题标题】:GetImageSize() not returning FALSE when it shouldGetImageSize() 不应该返回 FALSE
【发布时间】:2012-05-14 22:47:23
【问题描述】:

在这里处理一个小上传脚本。我正在尝试检查上传的图像是否真的是图像,而不仅仅是重命名的 PHP 文件。

脚本发布后,我可以使用

打印数组
foreach ($_FILES['images']['name'] as $key => $value){             
        print_r(getimagesize($_FILES['images']['tmp_name'][$key]));

这很好用,所以它不会返回 false。但即使我上传一个不是图片的文件,它也不会给出假的。它什么都不返回,我的脚本的其余部分只是像处理图像一样处理。

谁能告诉我我做错了什么?

【问题讨论】:

    标签: php validation getimagesize


    【解决方案1】:

    上传

    你不能直接在$_FILES['images']['tmp_name'][$key]上使用getimagesize..你需要先把它复制到你的系统中才能使用它

    暂时使用$_FILES['images']['size'][$key]

    或者

      move_uploaded_file($_FILES['images']['tmp_name'][$key], $destination);
      print_r(getimagesize($destination));
    

    假图片

    请注意$_FILES['images']['type'][$key] 是可以伪造的

    使用假图片标题

    例子

    file_put_contents("fake.png", base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABGdBTUEAALGPC/xhBQAAAAZQTFRF////
    AAAAVcLTfgAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH0gQCEx05cq
    KA8gAAAApJREFUeJxjYAAAAAIAAUivpHEAAAAASUVORK5CYII='));
    

    正在上传fake.png

    array
      'name' => 
        array
          0 => string 'fake.png' (length=8)
      'type' => 
        array
          0 => string 'image/png' (length=9)
      'tmp_name' => 
        array
          0 => string 'C:\Apache\xampp\tmp\php44F.tmp' (length=30)
      'error' => 
        array
          0 => int 0
      'size' => 
        array
          0 => int 167
    

    验证图像

    用法

    var_dump ( getimagesizeReal ( "fake.png" ) );
    

    使用的功能

    function getimagesizeReal($image) {
    
        $imageTypes = array (
                IMAGETYPE_GIF,
                IMAGETYPE_JPEG,
                IMAGETYPE_PNG,
                IMAGETYPE_SWF,
                IMAGETYPE_PSD,
                IMAGETYPE_BMP,
                IMAGETYPE_TIFF_II,
                IMAGETYPE_TIFF_MM,
                IMAGETYPE_JPC,
                IMAGETYPE_JP2,
                IMAGETYPE_JPX,
                IMAGETYPE_JB2,
                IMAGETYPE_SWC,
                IMAGETYPE_IFF,
                IMAGETYPE_WBMP,
                IMAGETYPE_XBM,
                IMAGETYPE_ICO 
        );
        $info = getimagesize ( $image );
        $width = @$info [0];
        $height = @$info [1];
        $type = @$info [2];
        $attr = @$info [3];
        $bits = @$info ['bits'];
        $channels = @$info ['channels'];
        $mime = @$info ['mime'];
    
        if (! in_array ( $type, $imageTypes )) {
            return false; // Invalid Image Type ;
        }
        if ($width <= 1 && $height <= 1) {
            return false; // Invalid Image Size ;
        }
    
        if($bits === 1)
        {
            return false; // One Bit Image .. You don't want that  ;
        }
        return $info ;
    }
    

    【讨论】:

    • 是的,但我不想移动上传的文件,除非我 100% 确定它是图像
    • 你先把它放在一个临时目录中..如果它不是一个有效的图像使用unlink删除它
    • 啊,我明白你的意思了!没想到。我马上试试。
    • 或者您可以使用 $_FILES['images']['type'][$key] 检查 MIME 类型以确保它是图像/png、图像/gif ...等在您上传之前。
    • 这很容易被欺骗...getimagesize 是迄今为止看到的最佳选择@Jamie Bicknell
    【解决方案2】:

    您可以简单地使用 $_FILES['images']['type'] 。它会给你上传文件的类型。然后再次检查八进制流或其他可执行文件。如果是这样,那就不允许它。

    【讨论】:

      【解决方案3】:

      首先,您可以在 $_FILES['images']['tmp_name'] 上使用 getimagesize,所以这不是问题。

      如果要检查文件是否为图像,请尝试以下操作:

      if(isset($_POST['submit'])) {
          $check = getimagesize($_FILES['images']['tmp_name']);
          if($check !== false) {
              echo 'File is an image - ' . $check['mime'];
          }
          else {
              echo 'File is not an image';
          }
      }
      

      【讨论】:

      • 我完全使用了你的代码(在 foreach 循环中),但它总是返回文件不是图像,无论它是否有效 =(
      • @user1362916 你是否完全复制了我的代码,因为我有一个类型并且使用 $_FILES['image'] 而不是你的 $_FILES['images']。我现在要更新sn-p
      【解决方案4】:

      在决定是否将上传的文件放在文档根目录的任何位置时,我建议不要相信getimagesize() 的结果。这是因为嵌入在 GIF 文件中的 PHP 代码(标题如 image.gif.php)将被 getimagesize() 识别为图像,但为它们提供服务除了显示图像外,还将运行其中的 PHP 代码。 Here 是有关该问题的更多信息。

      上面链接的文章建议设置一个单独的控制器,通过该控制器提供所有用户上传的文件。使用readfile() 读取的文件在通过本地文件系统访问时不会被解析。

      【讨论】:

        【解决方案5】:

        @user1362916 如果您使用 HTML 上传多张图片,那么您可能需要再添加一个这样的数组。

        if(isset($_POST['submit'])) {
            $check = getimagesize($_FILES['images']['tmp_name'][$i]);
            if($check !== false) {
                echo 'File is an image - ' . $check['mime'];
            }
            else {
                echo 'File is not an image';
            }
        }
        

        这里勾选[i],因为这是多文件上传。

        以下是完整的脚本

        <!DOCTYPE html>
        <html>
        <body>
        
        <form action="#" method="post" enctype="multipart/form-data">
            Select image to upload:
            <input name="my_files[]" type="file" multiple="multiple" />
            <input type="submit" value="Upload Image" name="submit">
        </form>
        
        
        <?php
        
         if (isset($_FILES['my_files']))
         {
            $myFile = $_FILES['my_files'];
            $fileCount = count($myFile["name"]);
        
        
                for ($i = 0; $i <$fileCount; $i++)
                 {
                   $error = $myFile["error"][$i]; 
        
                    if ($error == '4')  // error 4 is for "no file selected"
                     {
                       echo "no file selected";
                     }
                    else
                     {
                       if(isset($_POST['submit'])) {
                         $check = getimagesize($_FILES['my_files']['tmp_name'][$i]);
                         if($check !== false) {
                         echo 'File is an image - ' . $check['mime'];
                         }
                         else {
                         echo 'File is not an image';
                           }
                         }
        
                     }
               }  
         }
                ?>
        
        
        </body>
        </html>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-23
          • 2013-02-15
          • 1970-01-01
          • 1970-01-01
          • 2019-03-29
          • 2014-10-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多