PHP登录表单TypeError:getUserDataForUsername参数传入null
问题分析与解决方案
核心问题
致命错误的直接原因是getUserDataForUsername函数被传入null值,但该函数要求参数为字符串类型。此外代码还存在变量混淆、逻辑错误等问题,导致自定义错误提示无法正常触发。
具体问题点
- 类型错误触发:即使邮箱为空(
$username为null),仍调用getUserDataForUsername($username),违反函数的类型约束。 - 变量赋值错误:
$mcname被错误赋值为$_POST['password'],实际应对应表单的Minecraft用户名字段(如mcname)。 - 函数传参错误:将邮箱(
$username)传给getUserDataForUsername,而非Minecraft用户名,导致验证逻辑完全偏离需求。 - SQL查询缺失字段:仅查询
unique_id,但后续代码尝试访问userData['mcname']和userData['id'],这些字段未被检索。 - 无效的密码验证:对Minecraft用户名使用
password_verify,逻辑完全错误(Minecraft用户名不是密码哈希值)。
修复后的代码
1. 路由逻辑修正
if (strpos($route, '/login') !== false) { $isPost = strtoupper($_SERVER['REQUEST_METHOD']) === 'POST'; $email = ""; $mcUsername = ""; $errors = []; $hasErrors = false; if ($isPost) { // 获取表单输入(修正字段名) $email = filter_input(INPUT_POST, 'username'); // 假设邮箱字段名为username $mcUsername = filter_input(INPUT_POST, 'mcname'); // 修正为Minecraft用户名字段 // 验证邮箱不为空 if (empty($email)) { $errors[] = "E-Mail is empty"; } // 验证Minecraft用户名不为空 if (empty($mcUsername)) { $errors[] = "Minecraft name is empty"; } // 仅在Minecraft用户名非空时检查数据库存在性 if (!empty($mcUsername)) { $userData = getUserDataForUsername($mcUsername); // 传入正确的Minecraft用户名 if (empty($userData)) { $errors[] = "This player hasn't been on the server yet"; } } // 无错误时执行后续操作(如发送邮件、设置会话) if (empty($errors)) { $_SESSION['userID'] = (int) $userData['unique_id']; // 使用查询到的唯一ID // 在此添加发送邮件等逻辑 } } $hasErrors = !empty($errors); require __DIR__ . '/templates/login.php'; exit(); }
2. 数据库查询函数优化(可选)
如果需要更多字段,可调整SQL查询:
function getUserDataForUsername(string $username): array { // 按需选择所需字段 $sql = "SELECT unique_id, username FROM kype.cloud_players WHERE username=:username"; $statement = getDB()->prepare($sql); if (false === $statement) { return []; } $statement->execute([ ':username' => $username ]); // 无结果时返回空数组 return $statement->fetch() ?: []; }
关键修复说明
- 避免类型错误:仅在Minecraft用户名非空时调用
getUserDataForUsername,确保传入的参数始终为字符串。 - 修正变量逻辑:将Minecraft用户名的赋值改为对应表单字段,避免与密码字段混淆。
- 验证逻辑对齐需求:正确传入Minecraft用户名到数据库查询函数,实现"用户名存在"的验证。
- 移除无效代码:删除对Minecraft用户名的密码验证逻辑,符合需求中的验证规则。
- 安全空值检查:使用
empty()替代布尔值转换,更可靠地判断输入是否为空。
内容的提问来源于stack exchange,提问作者Noah F
相关产品推荐
相关产品推荐

