I need help with PHP file upload

Hello,
I feel miserable because I spent the last 3 days trying to solve this so I decided to request for help.

I created a form where users can apply for job position through the website. The most challenging part for me is the “upload CV”. the filename IS being displayed on the database…but the file itself is not showing in the destination I requested to code to upload it to (‘/uploads/’).

The upload code was in a different file called “uploadFile.php” and sisnce the form itself is taking action from another file I decided to move the upload code to the action file which is “create-form.php”. and Still no luck…

here are my codes:

jobForm.php:

<!DOCTYPE html>
<html>
<head>
    <title> Job Application Form </title>
</head>

<body>

<form action="../server/create-form.php" method="POST" name="addForm">
    <input type="text" name="fullName" placeholder="Full Name" />
    <input type="email" name="email" placeholder="E-mail Address" />
    <input type="number" name="mobile" placeholder="Mobile Number" />
    <!-- Birth Day -->
   <input type="date" name="dob" />
    <!-- Academic Degree -->
    <div>
        <select name="degree">
            <option value="High school">High School</option>
            <option value="Diploma">Diploma</option>
            <option value="Bachelor">Bachelor</option>
            <option value="Masters">Masters</option>
            <option value="PHD">PH.D</option>
        </select>
    </div>
    <!-- Years of EXP -->
    <div>
        <select name="expYears">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
            <option value="5">5</option>
            <option value="6">6</option>
            <option value="7">7</option>
            <option value="8">8</option>
            <option value="9">9</option>
            <option value="10">10</option>
            <option value="11">11</option>
            <option value="12">12</option>
            <option value="13">13</option>
            <option value="14">14</option>
            <option value="15">15</option>
            <option value="16">16</option>
            <option value="17">17</option>
            <option value="18">18</option>
            <option value="19">19</option>
            <option value="20">20</option>
        </select>
    </div>
    <!-- job position -->
    <div>
        <select name="jobPosition">
            <option name="jobPosition" selected ><?php echo $_GET['jobTitle']; ?></option>
            <option name="Web Developer" value="Web Developer">Web Developer</option>
            <option name="Web Designer" value="Web Designer">Web Designer</option>
            <option name="Graphic Designer" value="Graphic Designer">Graphic Designer</option>
            <option name="Data Scientist" value="Data Scientist">Data Scientist</option>
            <option name="Business Manager" value="Business Manager">Business Manager</option>
        </select>
    </div>
    <!-- why hire? -->
    <div>
        <textarea name="whyHire" placeholder="Why should we hire you?"></textarea>
    </div>
    <!-- Upload CV -->
    <div>
        <input type="file" name="uploadCV"/>
    </div>
    <!-- date applied -->
    <input type="hidden" name="dateApplied" value="<?php echo date('Y-m-d')?>" />
    <!-- Submit Form -->
    <input type="submit" name="addForm" value="Apply for this position"/>
</form>

</body>
</html>

create-form.php:

<?php

declare(strict_types=1);
// best removed if online
error_reporting(-1);
ini_set('display_errors', 'true');
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

//header("Location: http://localhost/Rocket/includes/thankYou.php");

include('connection.php');

if(isset($_POST['addForm'])) {

    $fullName = $_POST['fullName'];
    $email = $_POST['email'];
    $mobile = $_POST['mobile'];
    $dob = $_POST['dob'];
    $degree = $_POST['degree'];
    $expYears = $_POST['expYears'];
    $position = $_POST['jobPosition'];
    $whyHire = $_POST['whyHire'];
    $uploadCV = $_POST['uploadCV'];
    $dateApplied = $_POST['dateApplied'];


    $db = new Database();
    $db->connect();
    $db->insert('users',array('fullName'=>$fullName,'email'=>$email, 'mobile'=>$mobile,
                'dob'=>$dob, 'degree'=>$degree, 'expYears'=>$expYears, 'position'=>$position,
                'whyHire'=>$whyHire, 'uploadCV'=>$uploadCV, 'dateApplied'=>$dateApplied));  // Table name, column names and respective values
    $res = $db->getResult();
    print_r($res);

    if($res) {
        echo "Sent to DB";
        die();
    } else {
        echo "query error";
    }

    $file = $_FILES['uploadCV'];
    $fileName = $_FILES['uploadCV']['name'];
    $fileTmpName = $_FILES['uploadCV']['tmp_name'];
    $fileSize = $_FILES['uploadCV']['size'];
    $fileError = $_FILES['uploadCV']['Error'];
    $fileType = $_FILES['uploadCV']['type'];

    $fileExt = explode('.', $fileName);
    $fileActualExt = strtolower(end($fileExt));

    $allowed = array('jpg', 'jpeg', 'png', 'doc', 'docs', 'pdf');
    if(in_array($fileActualExt, $allowed) ) {
        if($fileError === 0) {
            if($fileSize < 50000 ) {
                $fileNameNew = uniqid('', true). '.' . $fileActualExt;
                $fileDestination = 'uploads/' . $fileNameNew;
                move_uploaded_file($fileTmpName, $fileDestination);
                echo "File uploaded!";
            } else {
                echo "File is too large...minimum size is 50MB";
            }
        } else {
            echo "there was a error uploading your file, please ty again!";
        }
    } else {
        echo "You can't upload this file type!";
    }
}

I presume you have echoed $fileDestination to see it contains what you expect?

Have you tried a simple form upload to see if that worked?

No, didn’t do that. I guess I will…

I’ve not checked all your code but try adding enctype="multipart/form-data" to your form tag.

Well, your code doesn’t actually make sense if you read it out loud. If you successfully inserted your data, you use a die(); and stop anything after that from executing including the uploading a file section. But when you have an error, you allow the file to execute. The logic behind it is very flawed and wrong. This is why I tend to brainstorm before I start a project. I talk to myself out loud what I want the code to do and how I want it to work. If the code I write isn’t what I said out loud, it doesn’t make sense.

Another problem I see is that if you are allowing someone to upload a file, you can’t use $_POST to reference it. You have to use $_FILES. - Never mind, I saw just the first $_POST['uploadCV'] which I assumed you were using to upload the file. A few lines below that, you are using $_FILES['uploadCV'].

Its giving me an eror now saying uploadCV is unidentified index…what???

<?php
//header("Location: http://localhost/Rocket/includes/thankYou.php");

include('connection.php');

if(isset($_POST['addForm'])) {

    $fullName = $_POST['fullName'];
    $email = $_POST['email'];
    $mobile = $_POST['mobile'];
    $dob = $_POST['dob'];
    $degree = $_POST['degree'];
    $expYears = $_POST['expYears'];
    $position = $_POST['jobPosition'];
    $whyHire = $_POST['whyHire'];
    $uploadCV = $_POST['uploadCV'];
    $dateApplied = $_POST['dateApplied'];


    $db = new Database();
    $db->connect();
    $db->insert('users',array('fullName'=>$fullName,'email'=>$email, 'mobile'=>$mobile,
        'dob'=>$dob, 'degree'=>$degree, 'expYears'=>$expYears, 'position'=>$position,
        'whyHire'=>$whyHire, 'uploadCV'=>$uploadCV, 'dateApplied'=>$dateApplied));  // Table name, column names and respective values
    $res = $db->getResult();
    print_r($res);

    if($res) {
        echo "Sent to DB";
        die();
    } else {
        echo "query error";
    }
}
include('./includes/uploadFile.php');

I don’t understand anymore

Don’t get so hasty. What I would do is save my original work as a backup and reference it to make sure I get most of the stuff I want. Then I would create a whole new file and then rewrite each code by parts starting with the database insert. You’re jumping this too fast and you’re making more mistakes because you’re being too hasty. My boss always says

Haste makes waste

Meaning that you are more likely to make more mistakes if you are in a hurry. Speaking of mistakes, Undefined index errors typically mean that you are referencing a variable that was never created. This also happens when you are trying to reference a $_POST, $_GET, or $_FILES index which was never created.

Take your time.

I’ll help you start your code.

if($_SERVER['REQUEST_METHOD'] == 'POST') {

	// Start your validation.

} else {

	// Change this line to whatever your form file was called.
	header('Location: back_to_the_form_file.php');
	die;

}
1 Like
 <input type="file" name="uploadCV"/>

“uploadCV” is a file input in your form, so it will appear in the $_FILES array, not in the $_POST array. So when you try to use it from $_POST, you get “undefined index”. You could have a separate form field of that same name but of a different type, perhaps a text box or a selection, which would appear in $_POST, but you haven’t. ETA : As @spaceshiptrooper said earlier, in fact.

1 Like

it is like that in the html already though :pensive:

Agreed. What I would do in normal circumstances is make sure the file is uploaded first before I insert the name and data. If it isn’t uploaded, I wouldn’t allow the data to be inserted. However, if the CV is optional, then you would have to figure out how you want it to proceed.

1 Like

The html is correct if you want to upload a file, but you should not reference it as $_POST['uploadCV'], it is $_FILES['uploadCV'], as you use after the query in the first code you posted.

weird, when I removed the

enctype="multipart/form-data"

the error of the index is gone

That’s not weird, it’s that setting that tells your browser to support multiple different types of input, specifically to add support for the input type="file" tag. It might have got rid of your error message, but it won’t allow your file to upload properly AFAIK.

Try it - var_dump($_POST) and see if it gives you enough information to upload the file.

2 Likes

I did this…

<form action="../includes/uploadFile.php"

and the upload worked :expressionless:
of course now the rest of the form won’t work so I will try to combine the codes

Great, I got things to work out. but now something else, the files are being uploaded which is very very great!
but the file name is not being displayed on the DB. any ideas?

You probably need to show us your updated code.

1 Like

It looks as though a text editor is being used to try and get the script to perform correctly. If so then try stepping through the script one line at a time and verifying the script is indeed showing the expected values at a particular point and only moving to the next break point once the values are correct.

<?php 
// break point
var_dump( $variableToInspect ); die;

This debug method is tedious but very thorough and far better than randomly changing a single line and hoping the desired result will be resolved.

<?php
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["uploadFile"]["name"]);
$uploadOk = 1;
$FileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if file is a actual image or fake image
if(isset($_POST["submit"])) {
    $check = getimagesize($_FILES["uploadFile"]["tmp_name"]);
    if($check !== false) {
        echo "File is an image - " . $check["mime"] . ".";
        $uploadOk = 1;
    } else {
        echo "File is not an image.";
        $uploadOk = 0;
    }
}
// Check if file already exists
if (file_exists($target_file)) {
    echo "Sorry, file already exists.";
    $uploadOk = 0;
}
// Check file size
if ($_FILES["uploadFile"]["size"] > 50000) {
    echo "Sorry, your file is too large.";
    $uploadOk = 0;
}
// Allow certain file formats
if($FileType != "jpg" && $FileType != "png" && $FileType != "jpeg"
    && $FileType != 'pdf' && $FileType != "doc" && $FileType != "docx" ) {
    echo "Sorry, only JPG, JPEG, PNG, PDF and Doc files are allowed.";
    $uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
    echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
    if (move_uploaded_file($_FILES["uploadFile"]["tmp_name"], $target_file)) {
        echo "The file ". basename( $_FILES["uploadFile"]["name"]). " has been uploaded.";
    } else {
        echo "Sorry, there was an error uploading your file.";
    }
}
?>

this code is uploading the files to the destination, but it doesn’t display the file name in the DB

Can you show the code that updates the database? There’s no query here.

<?php
//header("Location: http://localhost/Rocket/includes/thankYou.php");


include('connection.php');
include('../includes/uploadFile.php');

if(isset($_POST['addForm'])) {

    $fullName = $_POST['fullName'];
    $email = $_POST['email'];
    $mobile = $_POST['mobile'];
    $dob = $_POST['dob'];
    $degree = $_POST['degree'];
    $expYears = $_POST['expYears'];
    $position = $_POST['jobPosition'];
    $whyHire = $_POST['whyHire'];
    $uploadFile = $_POST['uploadFile'];
    $dateApplied = $_POST['dateApplied'];


    $db = new Database();
    $db->connect();
    $db->insert('users',array('fullName'=>$fullName,'email'=>$email, 'mobile'=>$mobile,
        'dob'=>$dob, 'degree'=>$degree, 'expYears'=>$expYears, 'position'=>$position,
        'whyHire'=>$whyHire, 'uploadCV'=>$uploadFile, 'dateApplied'=>$dateApplied));  // Table name, column names and respective values
    $res = $db->getResult();
    print_r($res);

    if($res) {
        echo "Sent to DB";
        die();
    } else {
        echo "query error";
    }

}

HTML form:

    <!-- Upload CV -->
<form name="addForm" action="../server/create-form.php" method="POST" enctype="multipart/form-data">
    <div>
        <input type="file" name="uploadFile" />
    </div>
</form>