0

I have extensively looked for a solution for this issue but none of the ones I have found seems to match my needs, so I kindly ask for help or ideas.

Short story: I am creating a reset password procedure for my website. This code should check if the email entered by the user in the page that is posting to this one is actually present in the db (table: users) and, if it is, it should create a token, add it to the table password_reset and send it to the user's email to complete the password reset procedure.

Error: The error that I get on the second query is "command out of sync", and I understands that it means that I cannot execute the query before I free up the result of the previous one. However, I need to use the result of the first query in the second, and for this reason I cannot free it up. What is the best solution to achieve my goal?

<?php

use PHPMailer\PHPMailer\PHPMailer;
require '../vendor/phpmailer/phpmailer/src/PHPMailer.php';
require '../vendor/phpmailer/phpmailer/src/SMTP.php';


require_once('./include/dbconnect.php');

$sendmail = 0; //initialize
$addtoken = 0; //initialize

date_default_timezone_set('UTC');

// Was the form submitted?
if (isset($_POST["ForgotPassword"])) {

    // Harvest submitted e-mail address
    if (filter_var($_POST["email"], FILTER_VALIDATE_EMAIL)) {
        $email = $_POST["email"];
    } else {
        echo "Please, enter a valid email address";
        exit;
    }

    // Check to see if a user exists with this e-mail exists
    if ($query = mysqli_prepare($db, "SELECT email, username FROM users WHERE email = ?")) {
        mysqli_stmt_bind_param($query, 's', $email);
        mysqli_stmt_execute($query);
        mysqli_stmt_bind_result($query, $selected_email, $selected_user);
        $userExists=mysqli_stmt_fetch($query);

        if ($userExists) {

        // Create a unique salt.
            $salt = "<salt code>";

        // Create the unique user password reset token
            $token = hash('sha512', $salt.$selected_email);

        // calculate the current timestamp
            date_default_timezone_set('UTC');
            $timestamp = mktime(date("H"), date("i"), date("s"), date("m"), date("d"), date("Y"));
            $curDate = date("Y-m-d H:i:s", $timestamp);
            $exp_timestamp = mktime(date("H"), date("i"), date("s"), date("m"), date("d")+1, date("Y"));
            $exp = date("Y-m-d H:i:s", $exp_timestamp);
           
        //If the email is already present in the reset database
            if ($query1 = mysqli_prepare($db, "SELECT expdate FROM password_reset WHERE email=?")) {
                mysqli_stmt_bind_param($query1, 's', $selected_email);
                mysqli_stmt_execute($query1);
                mysqli_stmt_bind_result($query1, $expdate);
                $entryExists = mysqli_stmt_fetch($query1);    
                } else {
                    die(mysqli_error($db));
                }

                if ($entryExists) { //if there is a result, meaning the pwd reset for this email has already been requested

                    echo "Password reset already contains this email";
                //if the token is still valid - do nothing
                    if ($expdate >= $curDate) {
                        echo "A password reset email has already been sent to this address. Please double check.";
                    } else {
                //if the token is expired - replace it with the new one

                    if ($query2 = mysqli_prepare($db, "UPDATE password_reset SET token = ?, expdate = ? WHERE email=?")){
                        mysqli_stmt_bind_param($query2, 'sss', $token, $exp, $selected_email);
                        mysqli_stmt_execute($query2);
                        $sendmail = 1;
                    
                    }


                }
            } else { //it means that a pwd reset hasn't been requested yet
            
                  $addtoken = 1;
                  $sendmail = 1;
            
            }

        } else { //there is no such user in the DB, so we do nothing
            $addtoken = 0;
            $sendmail = 0;
        }


        if ($addtoken==1){
            $insert = mysqli_prepare($db, "INSERT INTO password_reset (email, token, expdate) VALUES(?, ?, ?)");
            mysqli_stmt_bind_param($insert, 'sss', $selected_email, $token, $exp);
            mysqli_stmt_execute($insert);
        }


        if ($sendmail==1){...INSTRUCTIONS TO SEND EMAIL...}

  }

}

?>
TheEncoder
  • 58
  • 6
  • If you have pinpointed this issue to a specific query, it would be wise to reduce the amount of code in the question to isolate the problematic part. – El_Vanja Mar 30 '21 at 17:20
  • Also, have you taken a look at [this question](https://stackoverflow.com/questions/3632075/why-is-mysqli-giving-a-commands-out-of-sync-error)? – El_Vanja Mar 30 '21 at 17:21

0 Answers0