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()); } }
关键说明
- 必须通过
$mysqli->setAttribute(...)开启异常模式,否则唯一键冲突会直接抛出未捕获的致命异常。 - 用
try-catch包裹execute()调用,统一处理异常:捕获到1062错误码时提示邮箱重复,其他错误输出具体信息。 - 不要混用
if($stmt->execute())判断和异常捕获,二选一即可,新手用try-catch逻辑更清晰。
内容的提问来源于stack exchange,提问作者Tossik
相关产品推荐
相关产品推荐

