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

为何MySQL查询结果存入$_SESSION后显示为mysqli_result对象而非预期数值?

解决PHP登录验证中$_SESSION['roleid']返回mysqli_result对象而非数值的问题

嘿,我一眼就看出问题所在了——你直接把mysqli_query()返回的结果集对象赋值给了$_SESSION['roleid'],但这个对象并不是你要的数值,得从里面提取实际的role_id才行!

问题根源

mysqli_query()执行查询后,返回的是一个mysqli_result类型的对象,它代表了数据库查询的结果集合,而不是直接的字段值。你需要通过fetch方法从这个结果集里取出具体的数据。

快速修复方案

针对你现有的代码,只需要修改处理$result2的部分:

// 原来的错误代码:直接把结果集对象存session
// $_SESSION['roleid'] = $result2;

// 修改为:先从结果集中取出数据
if ($row2 = mysqli_fetch_assoc($result2)) {
    // 取出roles表的id字段值存入session
    $_SESSION['roleid'] = $row2['id'];
} else {
    // 如果没查到对应角色,跳转到错误页
    header("Location: ../index.php?login=error");
    exit();
}

或者如果你习惯用索引数组,可以用mysqli_fetch_row():

if ($row2 = mysqli_fetch_row($result2)) {
    $_SESSION['roleid'] = $row2[0]; // 第一个字段就是roles.id
}

更优的代码优化建议

除了修复这个问题,你的代码还有几个可以优化的地方,兼顾安全性和效率:

  1. 合并SQL查询,减少数据库请求
    你现在用了两个查询,其实可以通过JOIN合并成一个,一次查询拿到用户信息和角色ID:

    $sql = "SELECT u.id, u.name, u.email, r.id as role_id 
            FROM users u 
            JOIN roles r ON u.role_id = r.id 
            WHERE u.email = ? AND u.password = ?";
    
  2. 杜绝SQL注入风险
    你当前直接把POST参数拼进SQL语句,非常容易遭到SQL注入攻击。一定要用预处理语句:

    // 初始化预处理语句
    $stmt = mysqli_prepare($conn, $sql);
    // 绑定参数(s代表字符串,两个参数都是字符串类型)
    mysqli_stmt_bind_param($stmt, "ss", $Email, $Password);
    // 执行查询
    mysqli_stmt_execute($stmt);
    // 获取结果集
    $result = mysqli_stmt_get_result($stmt);
    // 取出数据
    if ($row = mysqli_fetch_assoc($result)) {
        $_SESSION['email'] = $row['email'];
        $_SESSION['roleid'] = $row['role_id'];
        header("Location: ../dashboard.php?login=success");
        exit();
    } else {
        header("Location: ../index.php?login=error");
        exit();
    }
    
  3. 密码安全:不要明文存储
    你的代码里直接比较明文密码,这是非常危险的做法。正确的流程是:

    • 用户注册时,用password_hash($password, PASSWORD_DEFAULT)生成哈希值存入数据库
    • 登录时,用password_verify($Password, $row['password'])来验证密码是否匹配

修改后的完整示例代码

<?php 
session_start(); 

if(isset($_POST['submit'])) { 
    include('CONFIG/config.php'); 
    include('CONFIG/db.php'); 

    $Email = trim($_POST['email']); 
    $Password = trim($_POST['password']); 

    // 错误处理:检查输入是否为空
    if(empty($Email) || empty($Password)) { 
        header("Location: ../index.php?login=empty"); 
        exit(); 
    }

    // 使用预处理语句查询用户和角色信息
    $sql = "SELECT u.id, u.name, u.email, u.password, r.id as role_id 
            FROM users u 
            JOIN roles r ON u.role_id = r.id 
            WHERE u.email = ?";
    
    $stmt = mysqli_prepare($conn, $sql);
    mysqli_stmt_bind_param($stmt, "s", $Email);
    mysqli_stmt_execute($stmt);
    $result = mysqli_stmt_get_result($stmt);
    
    if ($row = mysqli_fetch_assoc($result)) {
        // 验证密码(假设数据库存的是哈希值)
        if(password_verify($Password, $row['password'])) {
            $_SESSION['email'] = $row['email'];
            $_SESSION['roleid'] = $row['role_id'];
            header("Location: ../dashboard.php?login=success");
            exit();
        } else {
            header("Location: ../index.php?login=wrongpwd");
            exit();
        }
    } else {
        header("Location: ../index.php?login=nouser");
        exit();
    }
}else{ 
    header("Location: ../index.php?login=error"); 
    exit(); 
} 

这样修改后,$_SESSION['roleid']就能正确存储你期望的数值(比如1)了,同时代码的安全性和效率也提升了不少。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:15:57