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

PHP读取MySQL多行数据仅返回第一条的问题排查求助

问题根源与修复方案

嘿,我一眼就看到问题出在哪了——你在内层循环里覆盖了外层查询的结果集变量!

你看,外层循环用$reponses存储module_cmds的查询结果,但当你执行内层的$reponses = $bdd->query(...)时,原来的$reponses(也就是外层的结果集)被直接替换成了内层module_params的查询结果。这样一来,外层的while ($donnee = $reponses->fetch())在第一次循环后,下一次调用fetch()时,操作的已经是内层的结果集了。而内层结果集遍历完之后就没有数据了,外层循环自然就终止了,所以你只能拿到第一条module_cmds的数据。

接下来给你两种修复思路:


方案1:给内层结果集换个变量名

这是最简单的修复方式,只需要把内层查询的结果集变量改成别的名字,避免和外层的$reponses冲突:

$array = array();
// 外层查询用单独的变量名
$cmdsResult = $bdd->query('SELECT * FROM module_cmds WHERE serverId=' . $donnees['server_id'] . ' ORDER BY module');
while ($donnee = $cmdsResult->fetch()){
    $array_param = array();
    // 内层用不同的变量,不会覆盖外层结果集
    $paramsResult = $bdd->query('SELECT * FROM module_params WHERE idModule=' . $donnee['id']);
    while ($donne = $paramsResult->fetch()){
        $array_param_in = array(
            'param' => $donne['paramName'],
            'value' => $donne['value']
        );
        array_push($array_param,$array_param_in);
    }
    $array_in = array(
        'module' => $donnee['module'],
        'hash' => $donnee['hash'],
        'params' => $array_param
    );
    array_push($array,$array_in);
}

方案2:用JOIN查询优化(更推荐)

嵌套查询不仅容易出变量冲突的问题,还会增加数据库的交互次数(每一条module_cmds数据都要发一次查询)。用LEFT JOIN把两张表关联起来,一次性获取所有数据,效率更高,也能避免变量冲突:

$array = array();
// 用LEFT JOIN关联两张表,一次性拿到所有需要的数据
$allResult = $bdd->query('SELECT mc.*, mp.paramName, mp.value 
                         FROM module_cmds mc
                         LEFT JOIN module_params mp ON mc.id = mp.idModule
                         WHERE mc.serverId=' . $donnees['server_id'] . ' 
                         ORDER BY mc.module');

// 临时数组用来按module分组存储数据
$tempData = array();
while ($donnee = $allResult->fetch()){
    $moduleId = $donnee['id'];
    // 如果是第一次处理这个module,先初始化基础信息
    if (!isset($tempData[$moduleId])) {
        $tempData[$moduleId] = array(
            'module' => $donnee['module'],
            'hash' => $donnee['hash'],
            'params' => array()
        );
    }
    // 如果有参数数据,添加到params数组
    if (!empty($donnee['paramName'])) {
        $tempData[$moduleId]['params'][] = array(
            'param' => $donnee['paramName'],
            'value' => $donnee['value']
        );
    }
}
// 把临时数组转成最终需要的格式
$array = array_values($tempData);

额外提醒:防范SQL注入!

你现在直接把$donnees['server_id']拼到SQL语句里,这是非常危险的做法,很容易被SQL注入攻击。建议用PDO的预处理语句来替代:

比如外层查询改成这样:

$stmt = $bdd->prepare('SELECT * FROM module_cmds WHERE serverId = ? ORDER BY module');
$stmt->execute([$donnees['server_id']]);
$cmdsResult = $stmt->fetchAll();

预处理语句会自动处理变量的转义,能有效避免SQL注入风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:19:13