Wrong first name and surname displayed in success message

I have a code below where it displays a list of students in a drop down menu:

     $validSubmission = isset($_POST['resetpass']) && $_POST['students'] && $_POST['newpass'] && $_POST['confirmpass'];

    		
        $sql = "SELECT StudentUsername, StudentForename, StudentSurname FROM Student ORDER BY StudentUsername";

        $sqlstmt=$mysqli->prepare($sql);

        $sqlstmt->execute();

        $sqlstmt->bind_result($dbStudentUsername, $dbStudentForename, $dbStudentSurname);

        $students = array(); // easier if you don't use generic names for data

        $studentHTML = "";
        $studentHTML .= '<select name="students" id="studentsDrop">'.PHP_EOL;
        $studentHTML .= '<option value="">Please Select</option>'.PHP_EOL;

        $outputstudent = "";

        while($sqlstmt->fetch())
        {
    	
    	$student = $dbStudentUsername;
        $firstname = $dbStudentForename;
        $surname = $dbStudentSurname;

                if (!$validSubmission && isset($_POST['students']) && $student == $_POST['students'])
        {
        $studentHTML .= "<option value='".$student."' selected='selected'>" . $student . " - " . $firstname . " " . $surname . "</option>".PHP_EOL;
    }else{
        $studentHTML .= "<option value='".$student."'>" . $student . " - " . $firstname . " " . $surname . "</option>".PHP_EOL;
    }

        }


        $studentHTML .= '</select>'; 

Now further down the script I have another block of code where it resets the student’s password and then performs a select statement to find the student whose password has been changed and then displays the success message:

    $errormsg = (isset($errormsg)) ? $errormsg : '';

    if(isset($_POST['resetpass'])){
    //get the form data
    $studentdrop = (isset($_POST['students'])) ? $_POST['students'] : '';
    $newpass = (isset($_POST['newpass'])) ? $_POST['newpass'] : '';
    $confirmpass = (isset($_POST['confirmpass'])) ? $_POST['confirmpass'] : '';

    //make sure all data was entered
    if($studentdrop != ""){
    if($newpass){
    if (strlen($newpass) <= 5){
    $errormsg = "Your Password must be a minimum of 6 characters or more";
    }else{
    if($confirmpass){
    if($newpass === $confirmpass){


    //Make sure password is correct
    $query = "SELECT StudentUsername FROM Student WHERE StudentUsername = ?";
    // prepare query
    $stmt=$mysqli->prepare($query);
    // You only need to call bind_param once
    $stmt->bind_param("s",$studentdrop);
    // execute query
    $stmt->execute();
    // get result and assign variables (prefix with db)
    $stmt->bind_result($dbStudentUsername);
    //get number of rows
    $stmt->store_result();
    $numrows = $stmt->num_rows();

    if ($numrows == 1){
    //encrypt new password
    $newpassword = md5(md5("93w".$newpass."ed0"));

    //update the db

    $updatesql = "UPDATE Student SET StudentPassword = ? WHERE StudentUsername = ?";										
    $update = $mysqli->prepare($updatesql);
    $update->bind_param("ss", $newpassword, $studentdrop);
    $update->execute();

    //make sure the password is changed

    $query = "SELECT StudentUsername, StudentForename, StudentSurname, StudentPassword FROM Student WHERE StudentUsername = ? AND StudentPassword = ?";
    // prepare query
    $stmt=$mysqli->prepare($query);
    // You only need to call bind_param once
    $stmt->bind_param("ss",$studentdrop,$newpassword);
    // execute query
    $stmt->execute();
    // get result and assign variables (prefix with db)
    $stmt->bind_result($dbStudentUsername, $dbStudentForename, $dbStudentSurname, $dbStudentPassword);
    //get number of rows
    $stmt->store_result();
    $numrows = $stmt->num_rows();

    if ($numrows == 1){
    $errormsg = "<span style='color: green'>Student " . $studentdrop . " - " . $dbStudentForename . " ". $dbStudentSurname . " has been Registered</span>";

    }
    else{
    $errormsg = "An error has occured, the Password was not Reset";
    }
    }

The problem I am getting is my success message.

If I select student: u0867587 - Bill Wright from the drop down menu, it is displaying in the success message:

Student u0867587 - Jack Trone has been Registered

The student’s username is correct in the success message but the name is wrong, it should say:

Student u0867587 - Bill Wright has been Registered

Why is it displaying the wrong name in the success meassage and how can I get it to display the correct name?

You never called $stmt->fetch(), which means your variables still have whatever value they held from earlier in your script.

Also, I’d suggest some changes to your code’s organization that can make it easier to spot errors and easier to manage overall. I strongly suggest reading From Flat PHP to Symfony2, which is a step-by-step guide to making your code more organized. (About two-thirds into the article, it starts introducing third-party libraries. You can stop reading at that point if you wish.)

So do I simply just need to add $stmt->fetch(), or is there a bit more coding I need to add? If its bit more coding can you show me what it should be please. And I will read your link you provided to set my code up correctly for the future

You simply need to fetch. In fact, you could do $stmt->fetch() in place of $stmt->store_result().

Im afraid you said that actually because I did do what you stated before you posted your second post but it doesn’t seem to work. If you look at my code I have a success message if uses has successfully reset password and fail message if user hasn’t successfully reset password (An error has occurred…) It displays the fail message everytime I submit the reset password when I included the $stmt->fetch();, if I remove that fetch, include the $stmt->store_result() again and then reset password, then I get the success message and the password changes in database but im back to square one as it displays the wrong student name in the success message.

Can you show the updated code you’re running?

 $errormsg = (isset($errormsg)) ? $errormsg : '';

    if(isset($_POST['resetpass'])){
    //get the form data
    $studentdrop = (isset($_POST['students'])) ? $_POST['students'] : '';
    $newpass = (isset($_POST['newpass'])) ? $_POST['newpass'] : '';
    $confirmpass = (isset($_POST['confirmpass'])) ? $_POST['confirmpass'] : '';

    //make sure all data was entered
    if($studentdrop != ""){
    if($newpass){
    if (strlen($newpass) <= 5){
    $errormsg = "Your Password must be a minimum of 6 characters or more";
    }else{
    if($confirmpass){
    if($newpass === $confirmpass){


    //Make sure password is correct
    $query = "SELECT StudentUsername FROM Student WHERE StudentUsername = ?";
    // prepare query
    $stmt=$mysqli->prepare($query);
    // You only need to call bind_param once
    $stmt->bind_param("s",$studentdrop);
    // execute query
    $stmt->execute();
    // get result and assign variables (prefix with db)
    $stmt->bind_result($dbStudentUsername);
    //get number of rows
    $stmt->store_result();
    $numrows = $stmt->num_rows();

    if ($numrows == 1){
    //encrypt new password
    $newpassword = md5(md5("93w".$newpass."ed0"));

    //update the db

    $updatesql = "UPDATE Student SET StudentPassword = ? WHERE StudentUsername = ?";										
    $update = $mysqli->prepare($updatesql);
    $update->bind_param("ss", $newpassword, $studentdrop);
    $update->execute();

    //make sure the password is changed

    $query = "SELECT StudentUsername, StudentForename, StudentSurname, StudentPassword FROM Student WHERE StudentUsername = ? AND StudentPassword = ?";
    // prepare query
    $stmt=$mysqli->prepare($query);
    // You only need to call bind_param once
    $stmt->bind_param("ss",$studentdrop,$newpassword);
    // execute query
    $stmt->execute();
    // get result and assign variables (prefix with db)
    $stmt->bind_result($dbStudentUsername, $dbStudentForename, $dbStudentSurname, $dbStudentPassword);
    //get number of rows
    $stmt->fetch();
    $numrows = $stmt->num_rows();

    if ($numrows == 1){
    $errormsg = "<span style='color: green'>Student " . $studentdrop . " - " . $dbStudentForename . " ". $dbStudentSurname . " has been Registered</span>";

    }
    else{
    $errormsg = "An error has occured, the Password was not Reset";
    }
    }

After some reading of the manual, it seems that num_rows will not return the correct result until after all rows have been fetched, all the way to the final NULL result that indicates no more rows. So, for example, this seems to work:

$stmt->fetch(); // returns the one and only row you're expecting
$stmt->fetch(); // returns NULL indicating no more rows

$numrows = $stmt->num_rows; // now num_rows will work correctly

Though, that isn’t my favored solution. Another way would be to check the result of fetch rather than the num_rows.

$fetchSuccess = $stmt->fetch();

if ($fetchSuccess) {
    // success
} else {
    // error
}

Another solution, and the one that deviates the least from your current code, would be to call both store_result and fetch.

$stmt->store_result(); // buffer all result rows so num_rows will work correctly
$stmt->fetch(); // stores result data in bound variables

Thank you very much. How do I mark the thread to show that this has been solved?