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

PHP+MySQL注册登录问题:重复邮箱未跳转成功页触发致命错误

问题

我用PHP和MySQL实现注册登录功能,输入已注册的邮箱时,并未如预期跳转到signup-success.html,反而触发了第45行的致命错误。尝试替换代码片段仍未解决问题,我是PHP新手,正跟着教程开发。

尝试过的代码片段:
第一个片段:

{
    $stmt->execute();
} catch (mysqli_sql_exception $e) {
    if ($e->getCode() == 1062) {
        die("email address is already taken");
    }
}

第二个片段:

$password_hash = password_hash($_POST["password"], PASSWORD_DEFAULT);

$mysqli = require __DIR__ . "/database.php";

$sql = "INSERT INTO user (name, email, password_hash)
        VALUES (?, ?, ?)";
        
$stmt = $mysqli->stmt_init();

if ( ! $stmt->prepare($sql)) {
    die("SQL error: " . $mysqli->error);
}

$stmt->bind_param("sss",
                  $_POST["name"],
                  $_POST["email"],
                  $password_hash);
                  
if ($stmt->execute()) {

    header("Location: signup-success.html");
    exit;
    
} else {
    
    if ($mysqli->errno === 1062) {
        die("email already taken");
    } else {
        die($mysqli->error . " " . $mysqli->errno);
    }
}     

网站显示的错误信息:

Fatal error: Uncaught mysqli_sql_exception: Duplicate entry 'email@seznam.cz' for key 'email' in D:\Programy\XAMPP\XAMPP\htdocs\login01\process-signup.php:45 Stack trace: #0 D:\Programy\XAMPP\XAMPP\htdocs\login01\process-signup.php(45): mysqli_stmt->execute() #1 {main} thrown in D:\Programy\XAMPP\XAMPP\htdocs\login01\process-signup.php on line 45

解决方法

错误核心原因是mysqli默认会抛出异常,你第二个代码片段里用if($stmt->execute())的判断逻辑,但当邮箱重复触发唯一键冲突时,execute()会直接抛出致命异常,根本走不到后面的else分支。

修改后的完整代码

$password_hash = password_hash($_POST["password"], PASSWORD_DEFAULT);

$mysqli = require __DIR__ . "/database.php";
// 设置mysqli以异常模式处理错误,确保冲突能被捕获
$mysqli->setAttribute(MYSQLI_ATTR_ERRMODE, MYSQLI_ERRMODE_EXCEPTION);

$sql = "INSERT INTO user (name, email, password_hash)
        VALUES (?, ?, ?)";
        
$stmt = $mysqli->stmt_init();

if ( ! $stmt->prepare($sql)) {
    die("SQL错误: " . $mysqli->error);
}

$stmt->bind_param("sss",
                  $_POST["name"],
                  $_POST["email"],
                  $password_hash);

try {
    $stmt->execute();
    header("Location: signup-success.html");
    exit;
} catch (mysqli_sql_exception $e) {
    // 1062是MySQL唯一键冲突的错误码
    if ($e->getCode() === 1062) {
        die("邮箱已被注册");
    } else {
        die("注册失败: " . $e->getMessage());
    }
}

关键说明

  1. 必须通过$mysqli->setAttribute(...)开启异常模式,否则唯一键冲突会直接抛出未捕获的致命异常。
  2. 用try-catch包裹execute()调用,统一处理异常:捕获到1062错误码时提示邮箱重复,其他错误输出具体信息。
  3. 不要混用if($stmt->execute())判断和异常捕获,二选一即可,新手用try-catch逻辑更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 04:05:21