无法使用phpmailer更新数据库中的密码
我正在尝试开发忘记密码系统。一切似乎都很好,甚至在我的登录屏幕页面上有密码更新的消息提示,但实际上它并没有在数据库中更新。我不明白为什么会这样。我还使用phpmailer发送电子邮件。任何帮助都会大有帮助 重置密码页面:无法使用phpmailer更新数据库中的密码,php,mysqli,Php,Mysqli,我正在尝试开发忘记密码系统。一切似乎都很好,甚至在我的登录屏幕页面上有密码更新的消息提示,但实际上它并没有在数据库中更新。我不明白为什么会这样。我还使用phpmailer发送电子邮件。任何帮助都会大有帮助 重置密码页面: <?php if(isset($_POST['reset-submit'])){ $selector=$_POST['selector']; $validator=$_POST['validator']; $password=$_POST['p
<?php
if(isset($_POST['reset-submit'])){
$selector=$_POST['selector'];
$validator=$_POST['validator'];
$password=$_POST['password1'];
$passwordRepeat=$_POST['password2'];
if(empty($password) || empty($passwordRepeat)){
echo "empty fields";
}
elseif($password!=$passwordRepeat){
echo "password did not match";
}
$expiryDate=date("U");
require "db.inc.php";
$sql="SELECT * FROM pwdreset WHERE pwdresetSelector=? AND pwdresetExpires >= ?;";
$stmt=mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt,$sql)){
echo "Could not validate your request";
}
else{
mysqli_stmt_bind_param($stmt,"ss",$selector,$expiryDate);
mysqli_stmt_execute($stmt);
$result=mysqli_stmt_get_result($stmt);
if(!$row=mysqli_fetch_assoc($result)){
echo "Could not validate your request";
}
else{
$tokenBin=hex2bin($validator);
$tokenCheck=password_verify($tokenBin,$row['pwdresetToken']);
if($tokenCheck===false){
echo "Could not validate your request";
}
elseif($tokenCheck===true){
$tokenEmail=$row['pwdresetEmail'];
$sql="SELECT * FROM users WHERE emailUsers=?;";
$stmt=mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt,$sql)){
echo "Could not validate your request";
}
else{
mysqli_stmt_bind_param($stmt,"s",$tokenEmail);
mysqli_stmt_execute($stmt);
$result=mysqli_stmt_get_result($stmt);
if(!$row=mysqli_fetch_assoc($result)){
echo "Could not validate your request";
}
else{
$sql="UPDATE users SET pwdUsers=? WHERE emailUsers=?;";
$stmt=mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt,$sql)){
echo "Could not validate your request";
}
else{
$newpasswordHash=password_hash($password,PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt,"ss",$tokenEmail,$newpasswordHash);
mysqli_stmt_execute($stmt);
$sql="DELETE FROM pwdreset WHERE pwdresetEmail=?;";
$stmt=mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt,$sql)){
header("Location: ../createnewpassword.php?error=sqlerror");
exit();
}
else{
mysqli_stmt_bind_param($stmt,"s",$tokenEmail);
mysqli_stmt_execute($stmt);
header("Location: ../login.php?resetpassword=success");
exit();
}
}
}
}
}
else{
echo "Could not validate your request";
}
}
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
}
else{
header("Location: ../index.php");
exit();
}
由于有这么多其他语句和通用消息,您的代码很难阅读。开发时,您希望显示易于识别的错误1。了解是什么导致了他们和2。妥善处理。这些消息只有在代码处于生产状态时才应该是通用的(没有mysql错误等)
我将您的代码放入一个函数中,使其易于处理和阅读
我想你的问题归结到这一行:
mysqli\u stmt\u bind\u param($stmt,“ss”,$newpasswordHash,$tokenEmail)代码>
您已反转更新的值的位置。如果我是为自己设计的,我可能只会使用一个类,并将其分解为不同的函数,因为这是一个相当大的代码块,可以执行多个函数
<?php
if(isset($_POST['reset-submit'])){
$selector=$_POST['selector'];
$validator=$_POST['validator'];
$password=$_POST['password1'];
$passwordRepeat=$_POST['password2'];
if(empty($password) || empty($passwordRepeat)){
echo "empty fields";
exit();
}
elseif($password!=$passwordRepeat){
echo "password did not match";
exit();
}
$expiryDate=date("U");
require "db.inc.php";
$reset = reset_password( $conn , $selector , $validator , $password );
if( ! $reset['Results'] ){
echo $reset['Msg'];
exit();
}
header("Location: ../login.php?resetpassword=success");
exit();
}
else{
header("Location: ../index.php");
exit();
}
function reset_password( $conn , $selector , $validator , $password ){
$sql="SELECT * FROM pwdreset WHERE pwdresetSelector=? AND pwdresetExpires >= ?;";
$stmt=mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt,$sql)){
mysqli_stmt_close($stmt);
mysqli_close($conn);
return [ 'Result' => false , 'Msg' => '1: SQL Error - ' . mysqli_error($conn) ];
}
mysqli_stmt_bind_param($stmt,"ss",$selector,$expiryDate);
if( ! mysqli_stmt_execute($stmt) ){
return [ 'Result' => false , 'Msg' => 'Failed to execute 1' ];
}
$result=mysqli_stmt_get_result($stmt);
if(!$row=mysqli_fetch_assoc($result)){
mysqli_stmt_close($stmt);
mysqli_close($conn);
return [ 'Result' => false , 'Msg' => 'Failed to find reset' ];
}
$tokenBin=hex2bin($validator);
if( ! password_verify($tokenBin,$row['pwdresetToken']) ){ //you can check against this directly. No need to put it into a variable.
mysqli_stmt_close($stmt);
mysqli_close($conn);
return [ 'Result' => false , 'Msg' => 'Incorrect Password' ];
}
$tokenEmail=$row['pwdresetEmail'];
mysqli_stmt_close($stmt);
$sql="SELECT * FROM users WHERE emailUsers=?;";
$stmt=mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt,$sql)){
mysqli_stmt_close($stmt);
mysqli_close($conn);
return [ 'Result' => false , 'Msg' => '2: SQL Error - ' . mysqli_error($conn) ];
}
mysqli_stmt_bind_param($stmt,"s",$tokenEmail);
if( ! mysqli_stmt_execute($stmt) ){
mysqli_stmt_close($stmt);
mysqli_close($conn);
return [ 'Result' => false , 'Msg' => 'Failed to execute 2' ];
}
$result=mysqli_stmt_get_result($stmt);
if(!$row=mysqli_fetch_assoc($result)){
mysqli_stmt_close($stmt);
mysqli_close($conn);
return [ 'Result' => false , 'Msg' => 'No User Found' ];
}
mysqli_stmt_close($stmt);
$sql="UPDATE users SET pwdUsers=? WHERE emailUsers=?;";
$stmt=mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt,$sql)){
mysqli_stmt_close($stmt);
mysqli_close($conn);
return [ 'Result' => false , 'Msg' => '3: SQL Error - ' . mysqli_error($conn) ];
}
$newpasswordHash=password_hash($password,PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt,"ss",$newpasswordHash,$tokenEmail); //you had these reversed. According to your SQL looks like it should be this way
if( ! mysqli_stmt_execute($stmt) ){
mysqli_stmt_close($stmt);
mysqli_close($conn);
return [ 'Result' => false , 'Msg' => 'Failed to execute 3' ];
}
mysqli_stmt_close($stmt);
$sql="DELETE FROM pwdreset WHERE pwdresetEmail=?;";
$stmt=mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt,$sql)){
mysqli_stmt_close($stmt);
mysqli_close($conn);
return [ 'Result' => false , 'Msg' => '4: SQL Error - ' . mysqli_error($conn) ];
}
mysqli_stmt_bind_param($stmt,"s",$tokenEmail);
if( ! mysqli_stmt_execute($stmt) ){
mysqli_stmt_close($stmt);
mysqli_close($conn);
return [ 'Result' => false , 'Msg' => 'Failed to execute 4' ];
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
return [ 'Result' => true , 'Msg' => 'Failed to execute 4' ];
}
我不想变得不友善,我也意识到每个人都必须从某个地方开始,但在我看来这就像是。我会加入更多的echo,特别是那些说你的更新正在执行的。如果您没有看到该消息,那么错误就在之前的代码中的某个地方,需要更多的echo来找出代码偏离了方向。我注意到您只使用了mysqli\u stmt\u close()
一次,而您使用了大量mysqli\u stmt\u init()
和mysqli\u stmt\u prepare()
。为了安全起见,我会更一致地使用mysqli_stmt_close()
。感谢您的评论,我确实撤销了$newpasswordHash和$tokenEmail,并粘贴了您的代码,但它返回了“找不到重置”。然后,这就为您指明了需要查看的方向。您可能打算执行pwdresetExpires