【问题标题】:How to check uploaded file type in PHP如何在 PHP 中检查上传的文件类型
【发布时间】:2011-10-08 23:18:07
【问题描述】:

我使用此代码检查图像的类型,

$f_type=$_FILES['fupload']['type'];

if ($f_type== "image/gif" OR $f_type== "image/png" OR $f_type== "image/jpeg" OR $f_type== "image/JPEG" OR $f_type== "image/PNG" OR $f_type== "image/GIF")
{
    $error=False;
}
else
{
    $error=True;
}

但有些用户抱怨他们在上传任何类型的图片时都会出错,而有些用户却没有收到任何错误!

我想知道这是否能解决问题:

if (mime_content_type($_FILES['fupload']['type']) == "image/gif"){...

有没有cmets?

【问题讨论】:

    标签: php file-upload


    【解决方案1】:

    永远不要使用$_FILES..['type']。其中包含的信息根本没有经过验证,它是一个用户定义的值。自己测试类型。对于图片,exif_imagetype 通常是一个不错的选择:

    $allowedTypes = array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF);
    $detectedType = exif_imagetype($_FILES['fupload']['tmp_name']);
    $error = !in_array($detectedType, $allowedTypes);
    

    或者,finfo functions 也很棒,如果您的服务器支持的话。

    【讨论】:

    • 我认为我的共享主机上没有启用这个扩展:extension=php_mbstring.dll extension=php_exif.dll
    • exif_imagetype 是否不可欺骗?
    • @assensi 您可能想了解$_FILES 中不同字段的含义:php.net/manual/en/features.file-upload.post-method.phptmp_name 是正确的。
    【解决方案2】:

    除了@deceze,你还可以finfo()查看非图片文件的MIME类型:

    $finfo = new finfo();
    $fileMimeType = $finfo->file($path . $filename, FILEINFO_MIME_TYPE);
    

    【讨论】:

      【解决方案3】:

      警告:以下答案实际上并未检查文件类型。它只检查名称。它不适合用于实际的安全目的。

      编辑:请勿使用此方法,因为它不提供安全检查。我把这个答案留在这里,这样没有人会像我一样犯同样的错误。


      我尝试了以下方法,它对我有用:

      $allowed =  array('gif','png' ,'jpg', 'pdf');
      $filename = $_FILES['input_tag_name']['name'];
      $ext = pathinfo($filename, PATHINFO_EXTENSION);
      if(!in_array($ext,$allowed) ) {
          echo 'error';
      }
      

      Source link

      【讨论】:

      • 警告!这绝对不会检查任何内容! 它所做的只是检查扩展名是否在您允许的数组中。如果您将myVirus.exe 重命名为myVirus.jpg,它将很好地通过您的函数。显然这不是你想要的......
      • 这是非常危险的......避免并且永远不要将它用于严重的文件检查问题
      【解决方案4】:

      在 PHP 5.5 中,我使用此函数获取文件类型并检查图像是否:

      function getFileType( $file ) {
          return image_type_to_mime_type( exif_imagetype( $file ) );
      }
      
      // Get file type
      $file_type = getFileType( 'path/to/images/test.png' );
      echo $file_type;
      // Prints image/png
      // 1. All images have mime type starting with "image"
      // 2. No other non-image mime types contain string "image" in it 
      

      那么你可以这样做:

      if ( strpos( $filetype, 'image' ) !== false ) {
          // This is an image 
      }
      

      mime 类型的完整列表:http://www.sitepoint.com/web-foundations/mime-types-complete-list/

      【讨论】:

        【解决方案5】:

        当然,您可以使用 exif 检查它是否是图像,但我认为更好的方法是使用 finfo,如下所示:

        $allowed_types = array ( 'application/pdf', 'image/jpeg', 'image/png' );
        $fileInfo = finfo_open(FILEINFO_MIME_TYPE);
        $detected_type = finfo_file( $fileInfo, $_FILES['datei']['tmp_name'] );
        if ( !in_array($detected_type, $allowed_types) ) {
            die ( 'Please upload a pdf or an image ' );
        }
        finfo_close( $fileInfo );
        

        【讨论】:

          【解决方案6】:

          我认为最好的方法是先使用getimagesize(),然后使用imagecreatefromstring()

              $size = getimagesize($filename);
              if ($size === false) {
                  throw new Exception("{$filename}: Invalid image.");
              }
              if ($size[0] > 2500 || $size[1] > 2500) {
                  throw new Exception("{$filename}: Image too large.");
              }
          
              if (!$img = @imagecreatefromstring(file_get_contents($filename))) {
                  throw new Exception("{$filename}: Invalid image content.");
              }
          

          检查getimagesize() 可以防止一些DoS 攻击,因为我们不必从用户提供的每个文件中尝试imagecreatefromstring(),无论是非图像文件还是文件太大。不幸的是,根据PHP docs 不能依赖于检查图像类型的内容。

          imagecreatefromstring() 最终尝试将文件作为图像打开 - 如果成功 - 我们就有了图像。

          【讨论】:

            【解决方案7】:

            这是一个我经常使用的简单的单行脚本。

            $image = "/var/www/Core/temp/image.jpg";
            $isImage = explode("/", mime_content_type())[0] == "image";
            

            基本上,我使用 mime_content_type() 来获取类似“image/jpg”的内容,然后用“/”分解它并检查数组的第一个元素,看看它是否显示“image”。

            我希望它有效!

            【讨论】:

            • 参见dirname($x) 而不是explode("/", $x)[0]
            【解决方案8】:

            最后一行很接近。您可以使用: if (mime_content_type($_FILES['fupload']['tmp_name']) == "image/gif"){...

            在我目前正在处理的情况下,我的$_FILES..['type'] 将自己报告为“text/csv”,而mime_content_type()finfo()(由其他人建议)报告“text/plain.”。正如@deceze 指出的那样,$_FILES..['type'] 仅有助于了解客户认为文件是什么类型。

            【讨论】:

              【解决方案9】:

              你可以试试这个

              $file_extension = explode('.',$file['name']);
              $file_extension = strtolower(end($file_extension));
              $accepted_formate = array('jpeg','jpg','png');
              if(in_array($file_extension,$accepted_formate)) {           
                echo "This is jpeg/jpg/png file";
              } else {
                echo $file_extension.' This is file not allowed !!';
              }
              

              【讨论】:

              • 这是检查文件扩展名,而不是 MIME 内容类型。
              猜你喜欢
              • 2010-09-23
              • 1970-01-01
              • 1970-01-01
              • 2013-01-04
              • 1970-01-01
              • 2015-07-21
              • 1970-01-01
              • 1970-01-01
              • 2012-01-29
              相关资源
              最近更新 更多