【问题标题】:Validating avatar images with PHP使用 PHP 验证头像图像
【发布时间】:2015-03-02 08:17:58
【问题描述】:

我在MySQL 数据库中有一个名为mediumblob 类型的照片的列,它可以是NULL

这应该代表显示在 Web 应用程序右上角的员工的小照片。

新员工通过表单插入MySQL 数据库。

<form action="insert" method="post" enctype="multipart/form-data">
   ...
   <label for="photo">Photo</label>
   <input type="file" name="photo">
   ...
</form>

照片将按如下方式进行验证:

  1. 可以卸载(表格中不会提供照片)

    如果提供了一些照片,否则

  2. 应该是图片类型

  3. 图片大小应该适合这个目的

  4. 图片的尺寸应该适合这个目的

到目前为止,这是我的验证代码的概要。 我已经创建了一些验证条件(1 和 2)。那些还好吗? 并且不知道如何创建条件3和4。

$file = $_FILES['photo']['tmp_name']
if (!isset($file))
{
    $image = ""; // 1), empty string will be inserted into the database
}
else {
    $image = addslashes(file_get_contents($_FILES['photo']['tmp_name']));
    $image_size = getimagesize($_FILES['photo']['tmp_name']);

    if ($image_size == FALSE) { 
      // 2) not an image file
      // display the form again with error message
    }

    // checking 3)
    // checking 4)
}

【问题讨论】:

  • 我建议添加扩展检查以确保安全nullcandy.com/php-image-upload-security-how-not-to-do-it
  • 如果我是你,我会使用 mime 类型。也看看斑马图像。这是一个优秀的非常简单的 php 库,这将使这变得轻而易举。 Zebra Image。它也是一个非常小的文件。它基本上利用了 PHP 的图像功能并对其进行了简化。
  • @Rafael mime-type 检查不安全...它是客户端控制的 [T]他的值完全在客户端的控制之下,而不是在 PHP 端检查。 - 我之前评论中的链接
  • @Rafael 查看我的第一条评论 ;)
  • @Mramaa 您的 cmets 具有误导性。在$_FILES中发送的['type']是客户端计算出来的,可以进行操作,但是作者并没有这样做,仍然可以使用PHP的Fileinfo扩展来生成自己的MIME判断。

标签: php image validation file-upload


【解决方案1】:

Best way to determine if a file is empty (php)? 用于第 1 点
第二点根本不完整(不安全):
例如。添加扩展检查:PHP check file extension
第 2 点的更多安全提示:http://nullcandy.com/php-image-upload-security-how-not-to-do-it/
第3点和第4点可以用getimagesize()filesize()覆盖
Get image dimensions
http://php.net/manual/en/function.filesize.php

【讨论】:

    【解决方案2】:

    对于条件 3,您可以使用:

    $filesize = filesize($filename);
    
    u get size of the file in bytes.
    
    
    For condition 4 u can use:
    
    list($width, $height) = getimagesize($_FILES['photo']['tmp_name']);
    
    where $width and $height is the dimension of image.
    

    【讨论】:

      【解决方案3】:

      您的代码没问题,您只需要添加以下几行即可满足您的所有要求:

      $image="";
      if (isset($_FILES["photo"]) && $_FILES["photo"]["error"] < 1){
          $file = $_FILES['photo']['tmp_name'];
          $imageInfo = getimagesize($file);
          if(is_array($imageInfo)){
               if($imageInfo[0]>30 && $imageInfo[0]<257 && $imageInfo[1]>30 && $imageInfo[1]<257){
                 //$imageInfo[0] is width and $imageInfo[1] is height, you can set limit according to your need. I set it to MIN: 31*31 AND MAX 256*256
                 // if you want square image then add " && $imageInfo[0]=$imageInfo[1]" in above-if-clause
      
                    $imageSize=filesize($file); //returns bytes in integer
                    if($imageSize> 250 && $imageSize<20481) // image size should be less then 20kb
                        $image = addslashes(file_get_contents($file));
                    else echo "Image file should not grater then 20 KB.";
               }
               else echo "Image dimension(width*height) should be 31*31 to 256*256.";
          }
          else echo "Wrong file. Upload a Image file.";
      }
      else echo "No file uploaded or Error in file uploaded.";
      
      if(trim($image)==""){
         //display form again
      }
      

      【讨论】:

        【解决方案4】:

        以下是一些包含在代码中的有用提示:

        $upload_error = isset( $_FILES['photo']['error'] ) ? $_FILES['photo']['error'] : UPLOAD_ERR_NO_FILE;
        if ($upload_error == UPLOAD_ERR_NO_FILE) {
            // 1) No file uploaded
            $image = null; // I changed the empty string into a null, to avoid the mediumblob allocating space for the empty string
        } elseif ($upload_error) {
            // 5) You forgot to check if the file upload failed
            switch ($upload_error) {
                case UPLOAD_ERR_INI_SIZE:
                case UPLOAD_ERR_FORM_SIZE:
                    $message = "file_too_big";
                    break;
                case UPLOAD_ERR_PARTIAL:
                    $message = "upload_not_complete";
                    break;
                case UPLOAD_ERR_EXTENSION:
                    $message = "bad_file_extension";
                    break;
                case UPLOAD_ERR_NO_TMP_DIR:
                case UPLOAD_ERR_CANT_WRITE:
                    $message = "internal_upload_error";
                    break;
                default:
                    $message = "unknown_upload_error";
                    break;
            } 
            header("Location: form.php?error=$message"); // Load form again and show error
            exit;
        } else {
            $file = $_FILES['photo']['tmp_name'];
            $file_size = $_FILES['photo']['size'];
            if ($file_size > 5242880) { // 5 Megabyte for example, but always less than 16 Megabytes, because you use mediumblob
                // 3) The image size is not suitable for this purpose
                header("Location: form.php?error=file_too_big"); // Load form again and show error
                exit;
            }
            $image_size = getimagesize($file);
            if ($image_size) {
                $width = $image_size[0];
                $height = $image_size[1];
                if ($width < 100 || $width > 1000 || $height < 100 || $height > 1000) {
                    // 4) Image dimensions are not suitable. Width/height are not between 100 and 1000 pixels
                    header("Location: form.php?error=dimensions_not_ok"); // Load form again and show error
                    exit;
                }
            } else {
                // 2) Not an image type
                header("Location: form.php?error=not_an_image"); // Load form again and show error
                exit;
            }
            $image = file_get_contents($file);
        }
        // now escape $image and save it to the database
        // But I suggest you not use addslashes() to escape binary data
        // Use parameterized queries / mysqli_real_escape_string() / mysql_real_escape_string() instead
        

        【讨论】:

          【解决方案5】:
                $userfile_name = $_FILES['image']['name'];
                   $userfile_tmp = $_FILES['image']['tmp_name'];
                   $userfile_size = $_FILES['image']['size'];
                   $filename = basename($_FILES['image']['name']);
                   $allowedExts = array("gif", "jpeg", "jpg", "png");
                   $extension = end(explode(".", $_FILES["image"]["name"]));
                   if(($userfile_size / 1024) < 4096){
                       if (isset($_FILES['image']['name']) && !empty($_FILES["image"]) && ($_FILES['image'] ['error'] == 0) && ($userfile_size / 1024 < 4096 ) && (($_FILES["image"]["type"] == "image/gif")
                  || ($_FILES["image"]["type"] == "image/jpeg")
                  || ($_FILES["image"]["type"] == "image/jpg")
                  || ($_FILES["image"]["type"] == "image/pjpeg")
                  || ($_FILES["image"]["type"] == "image/x-png")
                  || ($_FILES["image"]["type"] == "image/png")) && in_array($extension, $allowedExts)) {
                                  //Everything is ok, so we can upload the image.
                  }else{
          echo "Error in file Upload";
          }
                  }else{
              echo 'Oops!  Your file\'s size is to large.';
              }
          

          对于第 4 点,您需要在实际上传发生之前在客户端上执行一些操作。 使用(服务器端)php,您只能在文件上传后检查尺寸

          【讨论】:

            【解决方案6】:

            您可以使用以下 PHP 库: https://github.com/codeguy/Upload

            【讨论】:

              猜你喜欢
              • 2013-03-10
              • 1970-01-01
              • 2013-04-04
              • 1970-01-01
              • 2014-12-23
              • 1970-01-01
              • 1970-01-01
              • 2014-09-30
              • 2016-08-22
              相关资源
              最近更新 更多