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

升级LAMP后mysqli同步错误修复:db_query与db_fetch改写

解决mysqli "Commands out of sync" 错误的db_query/db_fetch函数改写方案

这个错误本质是数据库连接上存在未完全处理的残留结果集,新版mysqli启用严格模式后触发了该异常。以下是保留stmt_init/prepare/execute/store_result核心流程的改写方案,完全适配原有代码调用逻辑:

改写后的db_query函数

function db_query($q, $params = []) {
    global $mysqli; // 替换为你的全局mysqli连接变量
    // 核心修复:清理连接中未处理的残留结果集
    while ($mysqli->more_results()) {
        $mysqli->next_result();
        if ($res = $mysqli->store_result()) {
            $res->free();
        }
    }

    $stmt = $mysqli->stmt_init();
    if (!$stmt->prepare($q)) {
        trigger_error("SQL Prepare失败: " . $stmt->error, E_USER_ERROR);
        return false;
    }

    // 适配原有参数绑定逻辑(如果你的代码有自定义类型,可修改$types生成规则)
    if (!empty($params)) {
        $types = str_repeat('s', count($params)); // s=字符串,i=整数,d=浮点数,b=二进制
        $stmt->bind_param($types, ...$params);
    }

    if (!$stmt->execute()) {
        trigger_error("SQL Execute失败: " . $stmt->error, E_USER_ERROR);
        $stmt->close();
        return false;
    }

    // 保留store_result核心流程,兼容无结果的查询(如INSERT/UPDATE)
    if (!$stmt->store_result() && $stmt->errno !== 0) {
        trigger_error("Store Result失败: " . $stmt->error, E_USER_ERROR);
        $stmt->close();
        return false;
    }

    return $stmt;
}

改写后的db_fetch函数

function db_fetch($stmt) {
    if (!$stmt || $stmt->num_rows === 0) {
        $stmt->close();
        return false;
    }

    // 自动绑定结果字段,适配原有关联数组返回格式
    $meta = $stmt->result_metadata();
    $fields = [];
    $bindVars = [];

    while ($field = $meta->fetch_field()) {
        $fields[] = &$bindVars[$field->name];
    }
    call_user_func_array([$stmt, 'bind_result'], $fields);
    $meta->free();

    // 读取单行结果
    if ($stmt->fetch()) {
        $result = [];
        foreach ($bindVars as $key => $val) {
            $result[$key] = $val;
        }
        return $result;
    } else {
        // 结果读取完毕,释放资源避免残留
        $stmt->free_result();
        $stmt->close();
        return false;
    }
}

关键修复点说明

  1. 残留结果集清理:db_query开头的循环强制清空连接中所有未处理的结果集,从根源解决命令不同步问题
  2. 资源自动释放:db_fetch在结果读取完毕后主动调用free_result()和close(),避免资源残留
  3. 兼容原有逻辑:完全保留核心流程,原有代码中$stmt = db_query($sql); while ($row = db_fetch($stmt)) {}的调用方式无需修改
  4. 无结果查询兼容:处理了INSERT/UPDATE等无需返回结果的场景,避免store_result报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 20:22:24