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

PHP登录表单TypeError:getUserDataForUsername参数传入null

问题分析与解决方案

核心问题

致命错误的直接原因是getUserDataForUsername函数被传入null值,但该函数要求参数为字符串类型。此外代码还存在变量混淆、逻辑错误等问题,导致自定义错误提示无法正常触发。

具体问题点

  1. 类型错误触发:即使邮箱为空($username为null),仍调用getUserDataForUsername($username),违反函数的类型约束。
  2. 变量赋值错误:$mcname被错误赋值为$_POST['password'],实际应对应表单的Minecraft用户名字段(如mcname)。
  3. 函数传参错误:将邮箱($username)传给getUserDataForUsername,而非Minecraft用户名,导致验证逻辑完全偏离需求。
  4. SQL查询缺失字段:仅查询unique_id,但后续代码尝试访问userData['mcname']和userData['id'],这些字段未被检索。
  5. 无效的密码验证:对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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 07:31:20