简体   繁体   English

文件上传验证PHP的问题

[英]Issue with file uploads validation PHP

I've been having on and off problems with this. 我一直在与此有关的问题。 It's very inconsistent. 这非常不一致。 I have a form where there is a title (input), short description (input), full description (textarea) and images uploads. 我有一个表格,其中有标题(输入),简短描述(输入),完整描述(文本区域)和图像上传。 (All relevant code below). (以下所有相关代码)。

After pressing submit on the form, a PHP script is run to handle the file uploads. 在表单上按Submit之后,将运行PHP脚本来处理文件上传。 Before each file is moved from its temporary location, it goes through a series of if statements to be validated. 在将每个文件从其临时位置移动之前,它会经过一系列要验证的if语句。 If it fails the validation stage, the else statement of that condition is applied and a PHP session, 'reason', is set to a word depending on the issue. 如果验证阶段失败,则应用该条件的else语句,并根据问题将PHP会话“原因”设置为一个单词。 (ie $_SESSION['reason']="invalidfile'). The user is then redirected back to the form page where, depending on what 'reason' is set to, the user is shown a specific error. The first validation condition works (check all the fields have been filled in). However, none of them work after that one. Except for the fact that sometimes they do. (即$ _SESSION ['reason'] =“ invalidfile')。然后,将用户重定向回表单页面,在该页面上,根据设置的“原因”,向用户显示特定错误。第一个验证条件有效(检查所有字段是否均已填写。)但是,在那之后,它们都不起作用,除了有时它们确实起作用。

Any help on this issue would be much appreciated. 在这个问题上的任何帮助将不胜感激。 It may also be useful to know that, sometimes, in Chrome, the images upload but the page never redirects further to the confirm page. 有时在Chrome中上传图片,但该页面再也不会重定向到确认页面,这也可能很有用。 This never happens in Microsoft Edge. 这在Microsoft Edge中永远不会发生。

HTML Form - Title, Short Description, Full Description, Image Files HTML表单-标题,简短描述,完整描述,图像文件

// If there is a file uploaded when you redirect back from the confirm page and 'return' is set in the header.
  if(isset($_SESSION['file'])){
    // For every image uploaded:
    for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
      // Delete the image because the user is forced to reupload them anyway.
      unlink($_SESSION['file']['destination'][$i]);
    }

    // Unset the 'file' session now we don't need it anymore
    unset($_SESSION['file']);
    header("Location: index.php?page=createproject");
  }
?>

<h1>Create Project</h1>
<p><a href="index.php?page=admin">Go back</a></p>

<form action="index.php?page=createprojectstorefiles" method="post" enctype="multipart/form-data">
  <p>Project Title: <input type="text" name="title" maxlength="35" autocomplete="off"
    <?php
    if(isset($_SESSION['project_details'])){
      echo "value='".$_SESSION['project_details']['title']."'";
    }
    ?>
    /></p>
  <p>Project Images: <input type="file" name="file[]" accept=".png, .jpg, .jpeg" multiple/></p>
  <p><label for="textarea" style="vertical-align: top; margin-right: 5px;">Short Descritption: </label><textarea name="short_description" rows="4" cols="60" maxlength="80" style="resize: none;"><?php
      if(isset($_SESSION['project_details'])){
        echo $_SESSION['project_details']['short_description'];
      }
    ?></textarea></p>
  <p><label for="textarea" style="vertical-align: top; margin-right: 5px;">Full Story: </label><textarea name="long_description" rows="15" cols="125" maxlength="5000" style="resize: none;"><?php
      if(isset($_SESSION['project_details'])){
        echo $_SESSION['project_details']['long_description'];
      }
    ?></textarea></p>

  <?php
    // If a reason has been sent for the form not working and the user hasn't been logged out.
    if(isset($_SESSION['reason'])){

      // If a 'reason' has been sent for not logging in.
      if(isset($_SESSION['reason'])){

        // Tell the user the reason.
        if($_SESSION['reason']=="noinput"){
          echo "<p><font color='red'><span class='error'>You can't leave any boxes blank</span></font></p>";
        } elseif($_SESSION['reason']=="invalidfile"){
          echo "<p><font color='red'><span class='error'>The file must be a '.jpg', '.jpeg' or '.png'</span></font></p>";
        } elseif($_SESSION['reason']=="uploaderror"){
          echo "<p><font color='red'><span class='error'>There was an error uploading your image!</span></font></p>";
        } elseif($_SESSION['reason']=="filetoolarge"){
          echo "<p><font color='red'><span class='error'>Your file is too large. The max file size is 500MB</span></font></p>";
        } elseif($_SESSION['reason']=="success"){
          header("Location: index.php?page=createprojectconfirm");
        } else{
          echo "<p><font color='red'><span class='error'>Something went wrong in validation, contact a network administrator</span></font></p>";
        }

        // Once the user has been told, unset the session.
        unset($_SESSION['reason']);

      // Otherise, presume that it's due to an incorrect username or password.
      } else{
        echo "<p><font color='red'><span class='error'>Something went wrong in validation, contact a network administrator</span></font></p>";
      }
    }
  ?>

  <p><button type="reset">Reset Form</button> <button type="submit" name="createproject">Preview Project</button></p>
</form>

PHP Script - Validate and move the uploaded files from the temp folder PHP脚本-验证并从temp文件夹移动上载的文件

    // Make sure no reason is set.
  if(isset($_SESSION['reason'])){
    unset($_SESSION['reason']);
  }

  if(isset($_SESSION['file'])){
    unset($_SESSION['file']);
  }

  // If the create project form has been submitted:
  if(isset($_POST['createproject'])){

    // Set all of the variables for the other text boxes in a session called 'project_details'.
    $_SESSION['project_details']['title'] = $_POST['title'];
    $_SESSION['project_details']['short_description'] = $_POST['short_description'];
    $_SESSION['project_details']['long_description'] = $_POST['long_description'];

    // If all of the fileds have been filled in:
    if(!empty($_POST['title']) && $_FILES['file']['error'][0]=='UPLOAD_ERR_OK' && !empty($_POST['short_description']) && !empty($_POST['long_description'])){

      // Count the number of files uploaded.
      $fileCount = count($_FILES['file']['name']);
      $_SESSION['file']['count'] = $fileCount;

      // Do for every uploaded file.
      for($i = 0; $i < $fileCount; $i++){

        // Set all of the variables for the file upload (file $i).
        $file = $_FILES['file'];

        $_SESSION['file']['name'] = $_FILES['file']['name'][$i];
        $_SESSION['file']['tmpName'] = $_FILES['file']['tmp_name'][$i];
        $_SESSION['file']['size'] = $_FILES['file']['size'][$i];
        $_SESSION['file']['error'] = $_FILES['file']['error'][$i];
        $_SESSION['file']['type'] = $_FILES['file']['type'][$i];

        $fileExt = explode(".", $_SESSION['file']['name']);
        $_SESSION['file']['actualExt'] = strtolower(end($fileExt));

        $allowed = array("jpg", "jpeg", "png");

        // If the file type is allowed:
        if(in_array($_SESSION['file']['actualExt'], $allowed)){

          // If there was no error uploading the file:
          if($_SESSION['file']['error'] == 0){

            // If the file isn't too large:
            if($_SESSION['file']['size'] < 500000){

              // Move the file from the temporary location to the new destination and set $_SESSION['reason'] to success so the page redirects to the confirm page. This shouldn't have to be neccesary to make it work but it is. No body on earth knows why.
              $fileNameNew = uniqid("", true).".".$_SESSION['file']['actualExt'];
              $_SESSION['file']['destination'][$i] = "projects/uploads/".$fileNameNew;
              move_uploaded_file($_SESSION['file']['tmpName'], $_SESSION['file']['destination'][$i]);

          // Otherwise, inform the user.
            } else{
              for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
                // Delete the image because the user is forced to reupload them anyway.
                unlink($_SESSION['file']['destination'][$i]);
              }

              $_SESSION['reason']="filetoolarge";
              header("Location: index.php?page=createproject");
              exit();
            }

          // Otherwise, inform the user.
          } else{
            for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
              // Delete the image because the user is forced to reupload them anyway.
              unlink($_SESSION['file']['destination'][$i]);
            }

            $_SESSION['reason']="uploaderror";
            header("Location: index.php?page=createproject");
            exit();
          }

        // Otherwise, inform the user.
        } else{
          for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
            // Delete the image because the user is forced to reupload them anyway.
            unlink($_SESSION['file']['destination'][$i]);
          }

          $_SESSION['reason']="invalidfile";
          header("Location: index.php?page=createproject");
          exit();
        }
      }

      // After all the files have been uploaded, if the header function doesn't work, use the session method to redirect to the complete page.
      if(!header("Location: index.php?page=createprojectconfirm")){
        $_SESSION['reason']="success";
        exit();
      }

    // Otherwise, inform the user.
    } else{
      $_SESSION['reason']="noinput";
      header("Location: index.php?page=createproject");
      exit();
    }
  } else{
    header("Location: index.php?page=admin");
    exit();
  }

The issue lied in the first block of code. 问题在于第一段代码。 At the top there is an if statement to unset the session 'file' if the user has returned from the preview page. 如果用户已从预览页面返回,则顶部的if语句将取消设置会话“文件”。 This contains a condition of if 'file' is set when loading the page. 这包含在加载页面时是否设置了“文件”的条件。 This scenario could also exist not just when the user has returned from the preview page because they choose to but also if there was an error. 这种情况可能不仅存在于用户因为选择退出预览页面而导致的错误时,还可能存在。 This if statement then reloads the page thus clearing the 'reason' session and the error doesn't show. 然后,此if语句重新加载页面,从而清除“原因”会话,并且不显示错误。

I fixed it by editing the conditions of the if statement. 我通过编辑if语句的条件来修复它。 By adding a check to make sure that the 'reason' session hasn't been set ie, there was no error but the user chose to return: 通过添加检查以确保未设置“原因”会话,即没有错误,但用户选择返回:

if(isset($_SESSION['file']) && !isset($_SESSION['reason'])){
    // For every image uploaded:
    for($i = 0; $i < count($_SESSION['file']['destination']); $i++){
      // Delete the image because the user is forced to reupload them anyway.
      unlink($_SESSION['file']['destination'][$i]);
    }

    // Unset the 'file' session now we don't need it anymore
    unset($_SESSION['file']);
    header("Location: index.php?page=createproject");
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM