foreach和for循环无法从sql查询中获取所有数据

问题描述

**已编辑

我将SQL查询分为3个,现在查询看起来像这样。

@H_502_5@$sql_2 = "SELECT disTINCT cr.id AS courseid,cr.fullname AS coursename,cr.idnumber AS idnumber,COUNT(disTINCT ra.id) AS enrols,COUNT(disTINCT cc.timecompleted) AS completed 
        FROM {course} cr JOIN {context} ct ON ( ct.instanceid = cr.id ) 
        LEFT JOIN {role_assignments} ra ON ( ra.contextid = ct.id ) and ra.roleid = 5 
        LEFT JOIN {course_completions} cc ON (cc.course = cr.id) 
        WHERE cr.id = :course_id GROUP BY cr.fullname,cr.id";

$sql_3 = "SELECT disTINCT 
        u.id AS userid,u.email AS email,u.lastaccess,c.id AS courseid
        FROM {user} u
        JOIN {role_assignments} ra ON ra.userid = u.id
        LEFT JOIN {context} ct ON ct.id = ra.contextid AND ra.roleid = 5
        LEFT JOIN {course} c ON c.id = ct.instanceid AND ct.contextlevel = 50
        WHERE c.id = :course_id";

$sql_4 = "SELECT disTINCT 
        u.id AS userid,sc.name AS item,m.name AS module,cm.id AS cmid,cm.idnumber AS itemidnumber,sc.launch AS launch,cmc.completionstate AS completed,cmc.timemodified AS timecompleted
        FROM {user} u
        JOIN {role_assignments} ra ON ra.userid = u.id
        LEFT JOIN {context} ct ON ct.id = ra.contextid AND ra.roleid = 5
        LEFT JOIN {course} c ON c.id = ct.instanceid AND ct.contextlevel = 50
        LEFT JOIN {course_modules} cm ON cm.course = c.id
        LEFT JOIN {course_modules_completion} cmc ON cmc.userid = u.id AND cmc.coursemoduleid = cm.id
        LEFT JOIN {modules} m ON m.id = cm.module
        LEFT JOIN {scorm} sc ON sc.id = cm.instance
        WHERE c.id = :course_id and m.id = 18";

$courses = $DB->get_records_sql($sql_2,["course_id" => $requestedcourseids]);
$users = $DB->get_records_sql($sql_3,["course_id" => $requestedcourseids]);
$modules = $DB->get_records_sql($sql_4,["course_id" => $requestedcourseids]);

我在每个结果下方添加了foreach和for循环,以获取多维数组结果,并获得了像这样的模块结果

@H_502_5@   "course": [
{
"courseid": 4,"coursename": "Activities","idnumber": "","enrols": 6,"completed": 1,"users": [
    {
        "userid": 3,"email": "[email protected]","lastaccess": 1599379804,"modules": [
            {
                "userid": 3,"module": "scorm","item": "Vitamin","itemidnumber": "","cmid": 24,"launch": 28,"timecompleted": 1595575023
            },{
                "userid": 2,"completed": 0,"timecompleted": 1593135761
            },{
                "userid": 4,"timecompleted": 1589359945
            },{
                "userid": 8,"completed": null,"timecompleted": null
            },{
                "userid": 7,"timecompleted": null
            }
        ]
    },{
        "userid": 2,"email": "[email protected]","lastaccess": 1599635370,"modules": [
            {
                "userid": 9,"timecompleted": 1595576987
            },{
                "userid": 3,

如您所见,模块列表仅显示一个模块以及每个用户ID。

它应该为每个用户列出8个不同的模块,但是它仅循环6次,这仅是用户数。我想让用户拥有用户尝试过的所有模块。

这是代码

@H_502_5@foreach($courses as $completion) {

if(!is_null($course)) {
    $coursesdata[] = $course;
}
$course = array();
$course['courseid'] = $completion->courseid;
$course['coursename'] = $completion->coursename;
$course['idnumber'] = $completion->idnumber;
$course['enrols'] = $completion->enrols;
$course['completed'] = $completion->completed;
$course['users'] = [];

if(!empty($users)) {
    foreach($users as $userinfo) {
        for($i=0; $i<count($users); $i++) {
            $user = array();
            $user['userid'] = $userinfo->userid;
            $user['email'] = $userinfo->email;
            $user['lastaccess'] = $userinfo->lastaccess;
            $user['modules'] = array();

            if(!empty($modules)) {
                foreach($modules as $details) {
                    for($i=0; $i<count($modules); $i++) {
                        $module = array();
                        $module['module'] = $details->module;
                        $module['item'] = $details->item;
                        $module['itemidnumber'] = $details->itemidnumber;
                        $module['cmid'] = $details->cmid;
                        $module['launch'] = $details->launch;
                        $module['completed'] = $details->completed;
                        $module['timecompleted'] = $details->timecompleted;
                    }
                    if(!is_null($module)) {
                        $user['modules'][] = $module;
                    }
                }
            }
        }
        if(!is_null($user)) {
            $course['users'][] = $user;
        }
    }
}
}

问题:如何将$ modules中的所有数据放在$ users数组下?目前,它仅循环$ modules查询中的第一个元素。

我已经尝试过注释和答案中建议的方法,但这是我到目前为止获得的最接近的方法

任何帮助或提示都将不胜感激。

谢谢!

解决方法

首先,您当前的代码容易受到sql注入的攻击,您确实应该使用参数https://api.highcharts.com/highcharts/series.polygon。我还将模块分解为另一个查询。

$sql_2 = "SELECT DISTINCT cr.id AS courseid,cr.fullname AS coursename,cr.idnumber AS idnumber,COUNT(DISTINCT ra.id) AS enrols,COUNT(DISTINCT cc.timecompleted) AS completed 
    FROM {course} cr JOIN {context} ct ON ( ct.instanceid = cr.id ) 
    LEFT JOIN {role_assignments} ra ON ( ra.contextid = ct.id ) and ra.roleid = 5 
    LEFT JOIN {course_completions} cc ON (cc.course = cr.id) 
    WHERE cr.id = :course_id GROUP BY cr.fullname,cr.id";

 $sql_3 = "SELECT DISTINCT 
        u.id AS userid,u.email AS email,c.id AS courseid
        FROM {user} u
        JOIN {role_assignments} ra ON ra.userid = u.id
        LEFT JOIN {context} ct ON ct.id = ra.contextid AND ra.roleid = 5
        LEFT JOIN {course} c ON c.id = ct.instanceid AND ct.contextlevel = 50
        WHERE c.id = :course_id and m.id = 18 ORDER BY u.email";
        
$sql_4 = "SELECT DISTINCT 
        u.id AS userid,m.name AS module
        FROM {user} u
        JOIN {role_assignments} ra ON ra.userid = u.id
        LEFT JOIN {context} ct ON ct.id = ra.contextid AND ra.roleid = 5
        LEFT JOIN {course} c ON c.id = ct.instanceid AND ct.contextlevel = 50
        LEFT JOIN {course_modules} cm ON cm.course = c.id
        LEFT JOIN {course_modules_completion} cmc ON cmc.userid = u.id AND cmc.coursemoduleid = cm.id
        LEFT JOIN {modules} m ON m.id = cm.module
        LEFT JOIN {scorm} sc ON sc.id = cm.instance
        WHERE c.id = :course_id and m.id = 18 ORDER BY u.email";

$courses = $DB->get_records_sql($sql_2,["course_id" => $requestedcourseids]);
$users = $DB->get_records_sql($sql_3,["course_id" => $requestedcourseids]);
$modules = $DB->get_records_sql($sql_4,["course_id" => $requestedcourseids]);

$course_user_modules = [];

foreach($courses as $course){
    $course["users"] = [];
    foreach($users as $course_user){
        if($course["courseid"]==$course_user["courseid"]){
            unset($course_user["courseid"]);
            $course_user["modules"] = [];
            foreach($modules as $user_module){
                if($user_module["userid"]==$course_user["userid"]){
                    unset($user_module["userid"]);
                    array_push($course_user["modules"],$user_module);
                }
            }
            array_push($course["users"],$course_user);
        }
    }
    array_push($course_user_modules,$course);
}
,

我在Moodle数据库调用get_records_sql

中发现了问题
$modules = $DB->get_records_sql($sql_4,["course_id" => $requestedcourseids]);

这将返回结果中第一个字段索引的数组。在我的情况下,这意味着每个用户ID仅返回一组数组。 在将sql查询的moduleid(唯一值)更改为第一位之后,它现在已按预期工作。

$sql_4 = "SELECT DISTINCT   cm.id AS moduleid,u.id AS userid,sc.name AS item,m.name AS module,cm.idnumber AS itemidnumber,sc.launch AS launch,cmc.completionstate AS completed,cmc.timemodified AS timecompleted
                            FROM {user} u
                            JOIN {role_assignments} ra ON ra.userid = u.id
                            LEFT JOIN {context} ct ON ct.id = ra.contextid AND ra.roleid = 5
                            LEFT JOIN {course} c ON c.id = ct.instanceid AND ct.contextlevel = 50
                            LEFT JOIN {course_modules} cm ON cm.course = c.id
                            LEFT JOIN {course_modules_completion} cmc ON cmc.userid = u.id AND cmc.coursemoduleid = cm.id
                            LEFT JOIN {modules} m ON m.id = cm.module
                            LEFT JOIN {scorm} sc ON sc.id = cm.instance
                            WHERE c.id = :course_id and m.id = 18 and u.id = :userid";

在出现之前,

users:
    userid: 2,module:
      moduleid: 12,userid: 8,module:
      moduleid: 12
    userid: 9,

现在我明白了,

users:
    userid: 2,moduleid: 14,moduleid: 17,userid: 9,

这篇文章帮助我进行了梳理。 get_records_sql returns only one result using inner join in moodle