Hello I have a script for validating the current password before updating it. It works but when I tried to update the email is shows Undefined variable: pass but in the other forms it is not even showing that error. How to fix?
Here is the html code.
<?php
$user_email = $_SESSION['user_email'];
$sql = "SELECT * FROM users WHERE user_email = '$user_email'";
$query = $conn->query($sql);
$row = $query->fetch_array();
// echo '<pre>' . var_export($_SESSION, true) . '</pre>';
?>
<div class="form-group">
<label class="d-flex justify-content-center"><strong>Update Information</strong></label>
<label>Fullname</label>
<input type="text" name="user_fullname" value="<?php echo $row['user_fullname']; ?>" class="form-control" placeholder="" required>
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="user_email" value="<?php echo $row['user_email']; ?>" class="form-control" placeholder="" required>
</div>
<div class="form-group">
<label>Current Password</label>
<input type="password" name="curpassword" class="form-control" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}"
title="Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters"
placeholder="Enter Current Password" required>
</div>
<div hljs-string">">
<label>Password</label>
<input type="password" name="password" hljs-string">" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}"
title="Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters"
placeholder="Enter New Password" required>
<input type="hidden" name="binder" value="<?php echo $user_email; ?>">
</div>
<div hljs-string">">
<label>Confirm Password</label>
<input type="password" name="cpassword" hljs-string">" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}"
title="Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters"
placeholder="Confirm Password" required>
</div>
<input type="submit" name="submitna" value="Update" hljs-string">">
</form>
</div>
<div hljs-string">">
<button data-dismiss="modal" hljs-string">" type="button">Close</button>
</div>
Here is the php script.
if(isset($_POST['submitna'])){
$binder = $_POST['binder'];
$user_fullname = $_POST['user_fullname'];
$user_email = $_POST['user_email'];
$curpassword = md5($_POST['curpassword']);
$password = md5($_POST['password']);
$cpassword = md5($_POST['cpassword']);
$sql = "SELECT * FROM users WHERE user_email = '$user_email' ";
$query = $conn->query($sql);
while($row = $query->fetch_array()){
$pass = $row['password'];
}
if($curpassword != $pass){
echo '<script>alert("Incorrect Current Password")
</script>';
}else if($password !== $cpassword){
echo '<script>alert("Password not matched")
window.location = "index.php"
</script>';
}else{
$sql="UPDATE users SET user_fullname=?, user_email=?, password=? WHERE user_email=?";
$stmt=$conn->prepare($sql);
$stmt->bind_param("ssss", $user_fullname, $user_email, $password, $binder);
if($stmt->execute()){
$_SESSION['user_email'] = $user_email;
echo '<script>alert("Information has been updated")
window.location = "index.php"
</script>';
}
}
}
The error only shows when I tried to change the email. What seems to be the cause of it?
CodePudding user response:
If there's no matching email, the while
loop that fetches the results will never execute, so you'll never set $pass
.
You need to check that the query returned a row of results before trying to use the variables you set from fetching.
f(isset($_POST['submitna'])){
$binder = $_POST['binder'];
$user_fullname = $_POST['user_fullname'];
$user_email = $_POST['user_email'];
$curpassword = md5($_POST['curpassword']);
$password = md5($_POST['password']);
if ($_POST['password'] != $_POST['cpassword']) {
echo '<script>alert("Password not matched");window.location = "index.php"</script>';
exit;
}
$sql = "SELECT * FROM users WHERE user_email = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $binder);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_array();
if (!$row) {
echo '<script>alert("Incorrect username")</script>';
} else {
$pass = $row['password'];
if($curpassword != $pass){
echo '<script>alert("Incorrect Current Password")</script>';
exit;
} else {
$sql="UPDATE users SET user_fullname=?, user_email=?, password=? WHERE user_email=?";
$stmt=$conn->prepare($sql);
$stmt->bind_param("ssss", $user_fullname, $user_email, $password, $binder);
if($stmt->execute()){
$_SESSION['user_email'] = $user_email;
echo '<script>alert("Information has been updated")
window.location = "index.php"
</script>';
}
}
}
}
Other points:
- Compare the plaintext password and password confirmation with each other, not their hashes and not with the database. If the confirmation doesn't match, there's no need to do anything with the database.
- Use prepared statements whenever a query contains user input.
- MD5 is not a secure password hash function. I didn't show it here, but you should use
password_hash()
andpassword_verify()
. - You should look up the old password using
$binder
, not$user_email
, just like you do in theUPDATE
query.$binder
is their old email from the hidden input,$user_email
is the new email they're changing it to.
CodePudding user response:
Your $pass variable is being created and set to the result row 'password' from this query: $sql = "SELECT * FROM users WHERE user_email = '$user_email' ";
Is the row 'password' in fact being returned by that query? If not, then $pass is not defined.