You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决PHP密码重置时的“Email not found”错误?

PHP密码重置功能“Email not found”错误排查与修复

我在实现PHP密码重置功能时遇到了“Email not found”错误提示,但通过SQL查询确认该邮箱确实存在于users表中。期望系统发送OTP到用户邮箱以完成密码重置,但当前流程无法正常执行。预期流程是用户获取含OTP的邮件后更新users表中的密码记录,目前无法实现。

相关代码

forgot-password.php

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title> </title>
    <h1 class="text-md-center">Reset Password</h1>
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <meta content="Free HTML Templates" name="keywords">
    <meta content="Free HTML Templates" name="description">

    <!-- Favicon -->
    <link href="img/favicon.ico" rel="icon">

    <!-- Google Web Fonts -->
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet"> 

    <!-- Font Awesome -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.0/css/all.min.css" rel="stylesheet">


    <!-- Libraries Stylesheet -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.carousel.min.css" rel="stylesheet">

    <!-- Customized Bootstrap Stylesheet -->
    <link href="css/style.css" rel="stylesheet">
    <link href="css/form-div-size.css" rel="stylesheet">
  
</head>


<body>
<div class="container">
  <div class="row justify-content-center">
    <div class="col-md-6">
      <div class="card mt-5">
        <div class="card-header">
          Reset Password
        </div>
        <div class="card-body">
          <form id="forgot-password"  action="reset-password-users.php" method="POST">
            <div class="form-group">
              <label for="email">Email</label>
              <input type="email" class="form-control" id="email" name="email" required>
            </div>
            <div class="form-group">
              <label for="new-password">New Password</label>
              <input type="password" class="form-control" id="new-password" name="new-password" required>
            </div>
            <div class="form-group">
              <label for="confirm-password">Confirm Password</label>
              <input type="password" class="form-control" id="confirm-password" name="confirm-password" required>
            </div>
           
            <button type="submit" class="btn btn-primary" name="submit">Reset Password</button>

          </form>
        </div>
      </div>
    </div>
  </div>
</div>

<!----Javascript files validation during form submission ---->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.validation/1.16.0/jquery.validate.min.js"></script>
<script>
  $(document).ready(function() {
  $('#forgot-password').validate({
    rules: {
      email: {
        required: true,
        email: true
      },
      'new-password': {
        required: true,
        minlength: 6
      },
      'confirm-password': {
        required: true,
        equalTo: '#new-password'
      }
    },
    messages: {
      email: {
        required: 'Please enter your email address',
        email: 'Please enter a valid email address'
      },
      'new-password': {
        required: 'Please enter a password',
        minlength: 'Your password must be at least 6 characters long'
      },
      'confirm-password': {
        required: 'Please enter the same password as above',
        equalTo: 'Your passwords do not match'
      }
    },
    errorElement: 'div',
    errorPlacement: function(error, element) {
      error.addClass('alert alert-danger');
      error.insertAfter(element);
    },
    success: function(label) {
      label.removeClass('alert-danger');
    },
    submitHandler: function(form) {
  // Generate a random OTP
  var otp = Math.floor(100000 + Math.random() * 900000);
  // Store the email and new password in the session
  sessionStorage.setItem('email', $('#email').val());
  sessionStorage.setItem('newPassword', $('#new-password').val());
  sessionStorage.setItem('otp', otp);
  // Redirect the user to the OTP confirmation page
  window.location.href = 'reset-password-users.php';
}


  });
});

</script>

</body>
</html>

reset-password-users.php

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once(__DIR__ . '/sendEmails/vendor/autoload.php');

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

// Database connection
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "ecommerce_store";

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Check if email exists in the database
    $email = $_POST['email'];
    $stmt = $conn->prepare("SELECT * FROM users WHERE email=:email");
    $stmt->bindParam(':email', $email);
    $stmt->execute();
    $users = $stmt->fetchAll();

    if (count($users) == 1) {
        // Generate OTP
        $otp = rand(100000, 999999);

        // Store OTP in the database
        $stmt = $conn->prepare("UPDATE users SET otp=:otp WHERE email=:email");
        $stmt->bindParam(':otp', $otp);
        $stmt->bindParam(':email', $email);
        $stmt->execute();

        // Send OTP to user's email
        $mail = new PHPMailer(true);
        $mail->isSMTP();
        $mail->Host = 'smtp.outlook.com';
        $mail->SMTPAuth = true;
        $mail->Username = 'user@example.com';
        $mail->Password = '****';
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port = 587;
        $mail->setFrom('gcizmandelegant@outlook.com', 'Your Name');
        $mail->addAddress($email, $users[0]['name']);
        $mail->Subject = 'Reset Password';
        $mail->Body = 'Dear ' . $users[0]['name'] . ',<br><br>Your OTP is: ' . $otp . '<br><br>Please enter this OTP to reset your password.<br><br>Best regards,<br>The Website Team';
        $mail->isHTML(true);

        $mail->send();

        // Redirect to OTP confirmation page
        $response = array('status' => 'success', 'message' => 'OTP sent to email.');
        header('Location: confirmation-otp.php?email=' . $email . '&message=' . urlencode($response['message']));
        exit();
    } else {
        // Redirect to reset password page with error message
        $response = array('status' => 'error', 'message' => 'Email not found.');
        header('Location: reset-password-users.php?message=' . urlencode($response['message']));

        exit();
    }
} catch(PDOException $e) {
    error_log("Error: " . $e->getMessage());
    // Redirect to reset password page with error message
    $response = array('status' => 'error', 'message' => 'Error resetting password. Please try again later.');
    header('Location: reset-password-users.php?message=' . urlencode($response['message']));
    exit();
}
?>

问题根源与修复方案

核心问题

前端表单的submitHandler中直接通过window.location.href跳转到reset-password-users.php,这是GET请求,但后端代码尝试从$_POST['email']获取邮箱值,导致后端无法拿到邮箱参数,数据库查询返回空,触发“Email not found”错误。同时前端提前生成OTP的逻辑与后端重复,造成数据不一致。

修复步骤

  1. 修改前端submitHandler逻辑
    删除前端OTP生成和sessionStorage存储代码,让表单正常以POST请求提交到后端:

    submitHandler: function(form) {
        // 直接提交表单,由后端处理OTP生成和发送
        form.submit();
    }
    
  2. 修正后端错误跳转地址
    当邮箱不存在或出现异常时,后端应跳转到表单页面forgot-password.php,而非自身:

    // 邮箱不存在时的跳转
    $response = array('status' => 'error', 'message' => 'Email not found.');
    header('Location: forgot-password.php?message=' . urlencode($response['message']));
    exit();
    
    // 异常捕获中的跳转
    header('Location: forgot-password.php?message=' . urlencode($response['message']));
    
  3. 在表单页面添加错误提示
    在forgot-password.php的表单上方添加代码,接收并显示后端传递的错误信息:

    <?php if(isset($_GET['message'])): ?>
        <div class="alert alert-danger"><?php echo htmlspecialchars($_GET['message']); ?></div>
    <?php endif; ?>
    
  4. 清理冗余逻辑
    删除前端中关于OTP生成和sessionStorage的代码,所有OTP相关逻辑交由后端处理,保证数据一致性。


内容的提问来源于stack exchange,提问作者The01800

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 12:07:21