如何检测所选图像是否为有效图像?

时间:2012-03-29 05:16:39

标签: php image upload

我正在实现一个脚本,用于验证图像以便使用php上传。实际上,php脚本与gif,png和jpg图像文件配合得很好,但是当我有一个条件:

  1. 我拍了一张图片theFileName.bmp,并将其扩展名重命名为theFileName.jpg
  2. 然后我选择要重命名的上传。
  3. 我在计算机上手动重命名了图像文件名,然后选择了要上传的文件。

    上传过程大约需要2到3秒,然后没有显示任何内容(甚至没有出现错误),只显示来自浏览器的默认消息:

      

    与localhost的连接中断。

    如何阻止用户选择不是实际有效图像的图像文件(以及任何其他文件)?

    此处的解决方案

    最后,我设法提出了自己的解决方案。这有点长,但至少它可以完成工作!希望它可以帮到某人。

    1. 它有助于防止用户上传不想要的mime-type
    2. 防止用户使用文本文件并重命名其扩展名等。
    3. 防止用户使用文本文件并更改其mime-type
    4. 防止该文件无法读取
    5. 防止文件包含错误
    6. 防止上传不是http
    7. 防止图像文件大小宽度:0,高度:0
    8. 还有更多事情需要验证和检查,以确保通过这种方式确保安全。

      # CHECK & TRY READ IMAGE FILE
      function is_readable_image( $theTmpFileloc ){
          try {
              if ( !getimagesize( $theTmpFileloc ) ){
                  # THE IMAGE IS UNREADABLE
                  return false;
              }
              # THE IMAGE IS READABLE
              return true;
      
          }catch( Exception $e ){
              # THE IMAGE IS OTHER FILE
              return false;
          }
      }
      # READ AND RETURN AN ARRAY OF IMAGE SIZES
      function get_image_size( $theTmpFileloc ){
          $imageSizes = array();
          $tmpResults = getimagesize( $theTmpFileloc );
          $imageSizes['width']  = $tmpResults[0];
          $imageSizes['height'] = $tmpResults[1];
      
          # IF EITHER WIDTH OR HEIGHT = 0, RETURN FALSE
          if ( $tmpResults[0] == 0 || $tmpResults[1] == 0 ) {
              return false;
          }
      
          return $imageSizes;
      }
      # READ AND RETURN AN IMAGE ACTUAL MIMETYPE
      function get_image_mime( $theTmpFileloc ){
          $imageMime  = '';
          $tmpResults = getimagesize( $theTmpFileloc );
          $imageMime  = $tmpResults['mime'];
      
          return $imageMime;
      }
      
      # START OF PHP TO VALIDATE IMAGE FILE
      if ( isset($_FILES['postImage']) && !empty($_FILES['postImage']['name']) ) {
          $tmpFileLoc      = $_FILES['postImage']['tmp_name'];
          $array_file_type = array('image/gif', 'image/png', 'image/x-png', 'image/jpeg', 'image/pjpeg');
      
          if ( $_FILES['postImage']['error'] == 1 ) {
              # THE IMAGE FILE CONTAINS ERROR
              $resMessage['Error']        = true;
      
          }elseif ( !is_uploaded_file( $tmpFileLoc ) ) {
              # PREVENT FROM UPLOADING FROM EXTERNAL SOURCE NOT HTTP
              $resMessage['Error']        = true;
      
          }elseif ( !is_readable_image( $tmpFileLoc ) ) {
              # PREVENT FROM IMAGE IS INVALID OR OTHER MIMETYPE
              $resMessage['Error']        = true;
      
          }elseif ( !get_image_size( $tmpFileLoc ) ) {
              # PREVENT FROM IMAGE SIZE 0, 0 OR INVALID ACTUAL MIMETYPE
              $resMessage['Error']        = true;
      
          }elseif ( !in_array( get_image_mime( $tmpFileLoc ), $array_file_type) ) {
              # LEVEL 2 OF CHECKING AN IMAGE MIMETYPE
              $resMessage['Error']        = true;
      
          }else {
              # other checks with file extension, max_size, 
              # dir is_writable and so on then move to move_uploaded_file
          }   
      }
      

2 个答案:

答案 0 :(得分:2)

为了给你的php脚本提供更多安全性,你应该使用getimagesize()。如果它返回FALSE则不是图像。还要确保文件不是太小。另外你可以使用GD库。

抱歉推迟了你。你应该在下次大声笑时给我们一个很好的例子。

答案 1 :(得分:0)

试试此代码

<?php
if (isset($_FILES['photo']))
{
    $mimetype = mime_content_type($_FILES['photo']['tmp_name']);
    if(in_array($mimetype, array('image/jpeg', 'image/gif', 'image/png'))) {
      move_uploaded_file($_FILES['photo']['tmp_name'],
      '/images/' . $_FILES['photo']['name']);
      echo 'OK';
    } else {
         echo 'Not an image file!';
    }
}