PHP注册提交跳转成功但用户数据未写入数据库问题排查
问题现象
使用PHP搭配HTML实现简易用户注册表单提交功能,已在数据库中创建名为users的用户表,表包含字段如下:
usersIdusersNameusersEmailusersUidusersPwd
表单提交后页面未抛出任何错误提示,跳转至注册成功状态,但用户提交的表单数据并未实际写入数据库。相关业务实现代码如下:
functions.inc.php
<?php function emptyInputSignup($name,$email,$username,$pwd,$pwdRepeat) { $result; if (empty($name) || empty($email) || empty($username) || empty($pwd) || empty($pwdRepeat)) { $result = true; } else { $result = false; } return $result; } function invalidUid($username) { $result; if (preg_match('/^[a-z]((?!__)[a-z\d_])+[a-z\d]$/i', $username)) { $result = true; } else { $result = false; } return $result; } function invalidEmail($email) { $result; if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $result = true; } else { $result = false; } return $result; } function pwdMatch($pwd, $pwdRepeat) { $result; if ($pwd !== $pwdRepeat) { $result = true; } else { $result = false; } return $result; } function uidExists($conn, $username, $email) { $sql = "SELECT * FROM users WHERE usersUid = ? OR usersEmail = ?;"; $stmt = mysqli_stmt_init($conn); if (!mysqli_stmt_prepare($stmt, $sql)) { header("location: ../signup.php?error=stmtfailed"); exit(); } mysqli_stmt_bind_param($stmt, "ss", $username, $email); mysqli_stmt_execute($stmt); $resultData = mysqli_stmt_get_result($stmt); if ($row = mysqli_fetch_assoc($resultData)) { return $row; } else { $result = false; return $result; } mysqli_stmt_close($stmt); } function createUser($conn, $name, $email, $username, $pwd) { $sql = "INSERT INTO users (usersName, usersEmail, usersUid, usersPwd) VALUES (?, ?, ?, ?);"; $stmt = mysqli_stmt_init($conn); if (!mysqli_stmt_prepare($stmt, $sql)) { header("location: ../signup.php?error=stmtfailed"); exit(); } $hashedpwd = password_hash($pwd, PASSWORD_DEFAULT); mysqli_stmt_bind_param($stmt, "ssss", $name, $email, $username, $hashedpwd); mysqli_stmt_execute($stmt); mysqli_stmt_close($stmt); header("location: ../signup.php?error=none"); exit(); }
signup.inc.php
<?php if (isset($_POST["submit"])){ $name = $_POST["name"]; $email = $_POST["email"]; $username = $_POST["uid"]; $pwd = $_POST["pwd"]; $pwdRepeat = $_POST["pwdrepeat"]; require_once 'dbh.inc.php'; require_once 'functions.inc.php'; if(emptyInputSignup($name,$email,$username,$pwd,$pwdRepeat) !== false){ header("location: ../signup.php?error=emptyinput"); exit(); } if(invalidUid($username) !== false){ header("location: ../signup.php?error=invaliduid"); exit(); } if(invalidEmail($email) !== false){ header("location: ../signup.php?error=invalidemail"); exit(); } if(pwdMatch($pwd, $pwdRepeat) !== false){ header("location: ../signup.php?error=pwddontmatch"); exit(); } if(uidExists($conn, $username, $email) !== false){ header("location: ../signup.php?error=usernametaken"); exit(); } createUser($conn, $name, $email, $username, $pwd); } else { header("location:../signup.php?error=none"); exit(); }
问题根因
按触发概率从高到低排序,共有3个核心问题:
- 前端提交按钮缺少必要属性
代码入口判断逻辑为isset($_POST["submit"]),如果前端表单的提交按钮没有添加name="submit"属性,POST参数中不会携带submit字段,代码会直接走最底部的else分支,直接跳转注册成功页,根本不会执行任何数据库校验、插入逻辑,自然不会有数据写入。 - 用户名校验逻辑完全颠倒
invalidUid函数的设计语义是用户名非法时返回true,但现有代码中,用户名匹配合法正则规则时返回true,不符合规则时返回false,等于合法用户名会被直接拦截,不符合规则的用户名反而能通过校验,极易触发后续数据库插入报错。 - 插入操作无错误捕获机制
createUser函数调用mysqli_stmt_execute()后没有判断执行结果,哪怕出现usersId未设置自增、字段长度不匹配、数据库连接异常等问题导致插入失败,代码也会直接关闭语句、跳转到注册成功页,不会抛出任何错误提示。
修复方案
按顺序修改对应代码即可:
- 检查前端注册表单的提交按钮,必须添加
name="submit"属性,示例:<button type="submit" name="submit">注册账号</button> - 修正
invalidUid函数的判断逻辑,正则不匹配时才判定为非法用户名:function invalidUid($username) { $result; if (!preg_match('/^[a-z]((?!__)[a-z\d_])+[a-z\d]$/i', $username)) { $result = true; } else { $result = false; } return $result; } - 给插入操作增加执行结果判断,同时确认数据库中
usersId字段已设置为自增主键,修改createUser函数的执行部分:mysqli_stmt_bind_param($stmt, "ssss", $name, $email, $username, $hashedpwd); if(!mysqli_stmt_execute($stmt)){ mysqli_stmt_close($stmt); header("location: ../signup.php?error=stmtfailed"); exit(); } mysqli_stmt_close($stmt); header("location: ../signup.php?error=none"); exit(); - 修改
signup.inc.php底部else分支的跳转逻辑,未正常提交表单时直接返回注册页即可,不要返回注册成功状态:else { header("location:../signup.php"); exit(); }
内容的提问来源于stack exchange,提问作者Steelux
相关产品推荐
相关产品推荐

