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

mysqli_query返回结果对象字段为null但可获取数据及num_rows判断失效的技术问询

问题分析与解决方案

咱们一步步拆解你遇到的核心问题:


1. 为什么日志里的$result对象属性全是null,但实际能获取到记录?

这是因为**mysqli_result是特殊的数据库结果对象,它的属性(比如num_rows、current_field等)并非普通可序列化的公共属性**。当你用json_encode()序列化它时,只能看到对象的表面结构,无法读取到它内部维护的真实数据(比如查询到的行数)。

你看到的日志输出只是json_encode()无法正确解析该对象后的“假象”,实际这个$result对象是有效的——所以你调用mysqli_fetch_assoc($result)时能拿到正确的用户数据。如果要在日志里查看真实的行数,直接输出$result->num_rows就行,别用json_encode():

error_log("Debug execute_db:: num_rows: " . $result->num_rows);

2. 为什么判断代码if (!$result || !$result->num_rows)无法达到预期效果?

看你给出的execute_db函数定义,发现了关键问题:这个函数没有返回查询结果!

你的函数里执行了mysqli_query()得到了$result,但最后没有用return $result;把结果返回给调用方。这意味着你在外面执行$result = execute_db(...)时,$result其实是PHP函数默认返回的null——这就会导致你的判断代码直接触发!$result的条件抛出异常,但你又说能拿到数据,说明你实际代码里可能漏写了return语句(或是测试时的小失误)。

修复方案:

首先,修改execute_db函数,确保它返回查询结果,同时增加错误处理:

function execute_db($query) {
    $connection = db_connect();
    // 执行查询并检查是否成功
    $result = mysqli_query($connection, $query);
    if (!$result) {
        error_log("Database query failed: " . mysqli_error($connection));
        mysqli_close($connection);
        return false;
    }
    
    // 打印真实的行数到日志
    error_log("Debug execute_db:: num_rows: " . $result->num_rows);
    error_log("Debug execute_db:: query: " . $query);
    
    // 记得关闭数据库连接(如果连接是复用的,可根据实际逻辑调整)
    mysqli_close($connection);
    
    // 返回结果对象给调用方
    return $result;
}

然后,调整你的判断代码,确保逻辑正确且避免PHP错误:

$result = execute_db("SELECT id FROM usuarios WHERE email = '$email'");

// 先检查查询是否成功,再检查是否有数据
if (!$result || $result->num_rows === 0) {
    throw new Exception(gettext("No existe una cuenta asociada a ese correo"));
}

// 然后获取数据
$user = mysqli_fetch_assoc($result);

额外建议:避免SQL注入风险

你的SQL语句直接把$email拼接到查询字符串里,存在严重的SQL注入风险。建议改用预处理语句:

function execute_db($query, $params = []) {
    $connection = db_connect();
    $stmt = mysqli_prepare($connection, $query);
    if (!$stmt) {
        error_log("Prepare failed: " . mysqli_error($connection));
        mysqli_close($connection);
        return false;
    }
    
    // 如果有参数,绑定参数并执行
    if (!empty($params)) {
        $types = str_repeat('s', count($params)); // 假设都是字符串类型,可根据实际调整
        mysqli_stmt_bind_param($stmt, $types, ...$params);
        if (!mysqli_stmt_execute($stmt)) {
            error_log("Execute failed: " . mysqli_stmt_error($stmt));
            mysqli_stmt_close($stmt);
            mysqli_close($connection);
            return false;
        }
        $result = mysqli_stmt_get_result($stmt);
    } else {
        $result = mysqli_query($connection, $query);
    }
    
    // 后续日志和返回逻辑
    error_log("Debug execute_db:: num_rows: " . $result->num_rows);
    mysqli_close($connection);
    return $result;
}

// 调用方式
$result = execute_db("SELECT id FROM usuarios WHERE email = ?", [$email]);

这样能有效防止SQL注入,让代码更安全。

内容的提问来源于stack exchange,提问作者Jorge Palacios Zaratiegui

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 18:48:15