0

I am trying to make a script in PHP which is a basic file upload function. Everything is done and everything works except the move_uploaded_file command. So what my program does in brief: You can upload an image from your PC and it renames it and uploads it to my localhost /uploads/ folder with a new name which is the current time. The problem is that, the program is not moves the file into the /uploads/ folder, but rename it, you can see it in the MYSQL Database, because the new path and name are correct. I am struggling with this one bug or error or I don't really know what it is. (Before the renaming function everything was working fine, you could upload your file into the /uploads/ folder). Any idea what should I do?

Code:

<?php
$con = mysqli_connect("localhost", "root", "", "dotech");
$target_dir = '/uploads/';
$target_file = $target_dir . basename($_FILES['fileToUpload']['name']);
$target_type = basename($_FILES['fileToUpload']['type']);
$target_ext = strtolower(end(explode('.',$_FILES['fileToUpload']['name'])));
$target_tmp = $_FILES['fileToUpload']['tmp_name'];
$target_size = $_FILES["fileToUpload"]["size"];
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
if(!$con) {
  die("Connection failed: " . mysqli_connect_error());
}

$user_id = mysqli_real_escape_string($con, $_POST['cpmsbtndbldsrd']);
$post_text = mysqli_real_escape_string($con, $_POST['user_post_textarea']);
$post_tag = mysqli_real_escape_string($con, $_POST['tag_select']);


if(isset($_POST["create_post"])) {
    $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
    if($check !== false) {
      $uploadOk = 1;
    } else {
      $uploadOk = 0;
      header("Location: /p/index.php?id=$user_id&fileupload=invalid_file_type");
      exit();
    }
    if ($uploadOk = 1) {
        $target_file = $target_dir.''.date('YmdHis').'.'.$target_ext;
        $post_file = $target_file;
        move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file);
        if ($stmt = $con->prepare('INSERT INTO user_posts (user_id, post_desc, post_file, post_file_type, post_file_size, post_tags) VALUES (?, ?, ?, ?, ?, ?)')) {
            $stmt->bind_param('isssis', $user_id, $post_text, $post_file, $target_type, $target_size, $post_tag);
            $stmt->execute();
            header("Location: /p/index.php?id=$user_id&fileupload=success");
            exit();
        } else {
            echo 'Could not prepare statement!';
        }
        $stmt->close();
    }
  }

?>

EDIT: So I made changes on my code and I have a new error or I don't even know what to call this. By the way, it finally move the renamed file into the /uploads/ folder, but not insert into the database.

CHANGES:

$tmp = explode('.', $target_name);  // New exploding method
$target_ext = @end($tmp);

if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)){
    $stmt = $con->prepare('INSERT INTO user_posts (user_id, post_desc, post_file, post_file_type, post_file_size, post_tags) VALUES (?, ?, ?, ?, ?, ?)');
        $stmt->bind_param('isssis', $user_id, $post_text, $post_file, $target_type, $target_size, $post_tag);
        $stmt->execute();
        header("Location: /p/index.php?id=$user_id&fileupload=success");
        exit();
} else {
    var_dump($_FILES["fileToUpload"]);
}

Error: Error message

scrummy
  • 795
  • 1
  • 6
  • 20
  • 1
    Side note: you should not be using mysqli_real_escape_string anywhere here, because you are already using prepared statements. escaping the data in this context can actively damage it – ADyson Jun 28 '21 at 17:31
  • 1
    Anyway, do you have errors and warnings switched on in PHP? Move_uploaded_file will issue a warning usually if it fails to work. At worst it will return `false` but currently your code doesn't check for that. I note you also don't check if there are any errors with the actual upload - looking at `$_FILES["fileToUpload"]["error"]` would tell you that – ADyson Jun 28 '21 at 17:34
  • 1
    Also `if ($uploadOk = 1) {` should be `if ($uploadOk == 1) {` - == is for comparison, = is for assignment – ADyson Jun 28 '21 at 17:36
  • 1
    And another aside - your sql error handling is inconsistent. You check if prepare fails, but not if bind_param or execute fails - they can all go wrong. Instead of laboriously checking each line individually, just set mysqli to show error messages automatically - see https://stackoverflow.com/a/22662582/5947043. If you want to then trap those errors (apart from using a global error handler in your application), then you can wrap all the mysqli-related code in a try/catch block. – ADyson Jun 28 '21 at 17:40
  • @ADyson thanks for your advices, I inserted the `$_FILES["fileToUpload"]["error"]` snippet and it says there is a problem with the `$target_ext = strtolower(end(explode('.',$_FILES['fileToUpload']['name'])));` part. The error message is `Only variables should be passed by reference`. – scrummy Jun 28 '21 at 17:46

1 Answers1

1

The move_uploaded_file() function will return the result of the operation, so you should check it before insert it to the database:

if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)){
// success
} else {
// try to debug it, var_dump($_FILES["fileToUpload"]); 
// The destination directory must exist, so check if $target_file path is available
}
zsocakave
  • 66
  • 2