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



**已编辑

我将sql查询拆分为3个,现在查询如下所示。

$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循环,以获得多维数组结果,并获得类似的模块结果

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

正如您所看到的,模块列表中每个用户ID只显示一个模块。

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

这是代码

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注入的攻击,您确实应该使用参数Moodle Documentation。我还将模块分解为另一个查询。

$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]);

这将返回一个由结果中的第一个字段索引的数组。这意味着在我的情况下,每个userid只返回一组数组。在我将moduleid(唯一值(的sql查询更改为优先之后,它现在可以按预期工作了。

$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,
module:
moduleid: 12,

现在我明白了,

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

这篇文章帮我整理了一下。get_records_sql在moodle 中使用内部联接只返回一个结果

最新更新