PHP password_verify returns NULL when parameters are the same

I have a problem with PHP function password_verify. I've written simple PHP function that uses _GET, takes 3 parameters: $user_unique_id, old_password and new_password. It verifies if old password and the password stored in database are the same. I use hash from my database and compare it with old password using password_verify() fucntion but it returns false even whem I'm 100% sure the passwords are the same. Can somebodyb help me with this problem? I've checked MySQL queries and all works very well. I return updated_at time which later I encode to JSON.

This is my function in main script changeuserpassword.php I call from link:

<?php
require_once 'include/DB_Functions.php';
$db = new DB_Functions();

// JSON Response Array
$response = array();

// Receiving The Post Params
$old_password = $_GET['old_password'];
$new_password = $_GET['new_password'];
$user_unique_id = $_GET['user_unique_id'];

// Change User Password
$user = $db->changeUserPassword($user_unique_id, $old_password, $new_password);

if ($user != false) {
    $response["error"] = false;
    $response["user"]["updated_at"] = $user["updated_at"];
    echo json_encode($response);
} else {
    $response["error"] = true;
    $response["error_msg"] = "Podano nieprawidłowe stare hasło";
    echo json_encode($response);    
}
?>

This is the function I use in changeuserpassword.php main script. It is called changeUserPassword:

/**
 * Change User Account Password
 */
public function changeUserPassword($user_unique_id, $old_password, $new_password) {
    $stmt = $this->conn->prepare("SELECT user.`encrypted_password` 
                                    FROM `user` 
                                    WHERE user.`unique_id` = ?");   // Preparing SELECT Query To The `user` Table
    $stmt->bind_param("s", $user_unique_id);                        // Binding With Params

    if ($stmt->execute()) {
        $user = $stmt->get_result()->fetch_assoc(); // Fetching Rows From Query
        $stmt->close();

        $password_hash = $user["encrypted_password"];   // Decrypting Hashed Password

        // Checking Currrent Password Identity With Decrypted Password
        if (password_verify($old_password, $password_hash)) {   // Old Password And Current One Are The Same
            $encrypted_password = password_hash($new_password, PASSWORD_DEFAULT);   // Hashing New Password

            $stmt = $this->conn->prepare("UPDATE user 
                                            SET user.`encrypted_password` = ?, user.`updated_at` = NOW() 
                                            WHERE user.`unique_id` = ?");
            $stmt->bind_param("ss", $encrypted_password, $user_unique_id);
            $result = $stmt->execute();
            $stmt-close();

            // Checking For Succesfull UPDATE
            if ($result) {
                $stmt = $this->conn->prepare("SELECT user.`updated_at` 
                                                FROM `user` 
                                                WHERE user.`unique_id` = ?");
                $stmt->bind_param("s", $user_unique_id);
                $stmt->execute();
                $user = $stmt->get_result()->fetch_assoc(); // Fetching Rows From Query
                $stmt->close();

                return $user;
            }
        } else {    // Old Password And Current One Are Different
            return false;
        }
    }
}

Edit

Here is my database screenshot: My script runs but it always return false which means password_verify() returns false.

Solved

The problem was $stmt->close() statement. I used them too often and thats why the script didn't work.

Answers


After debugging with @anton86993 in a chat, we found the bug to be the use of too many $sql->close() statements, when they weren't needed.

There is no reason to have that many close statements, as PHP automatically closes the connection to SQL when the script is done. A reason to have a close statement could be to release a connection to SQL, if you have a limited amount of connection at once or the obvious one to release resources.


Need Your Help