Moodle新活动创建成功但无法向数据库添加实例,出现“Error reading from database”错误求助
排查Moodle activity_add_instance无法插入数据库的问题
我来帮你一步步梳理这个问题,毕竟在开发Moodle插件时,数据库操作的隐性错误确实容易让人头疼。你提到活动创建成功,但testnew表没有新增数据,还出现了“Error reading from database”的提示,咱们从以下几个方向排查:
1. 确认数据库表结构是否匹配
Moodle的$DB->insert_record()会严格匹配表字段和传入对象的属性,如果testnew表有非空且无默认值的字段,但$data里没有赋值,插入就会失败。你可以通过以下方式检查:
- 直接查看数据库中
testnew表的字段结构,确认是否有必填字段遗漏; - 在函数里临时添加调试代码,打印表字段和
$data的内容:debugging('testnew表字段: ' . print_r($DB->get_columns('testnew'), true), DEBUG_DEVELOPER); debugging('传入的$data: ' . print_r($data, true), DEBUG_DEVELOPER);
2. 开启Moodle调试模式,暴露具体错误
默认情况下Moodle会隐藏详细错误信息,你需要修改config.php开启调试:
$CFG->debug = DEBUG_DEVELOPER; $CFG->debugdisplay = true;
这样再创建活动时,就能看到insert_record()失败的具体原因(比如字段类型不匹配、权限不足等),这是排查这类问题最有效的方法。
3. 给数据库操作添加异常捕获
Moodle的数据库操作失败时会抛出dml_exception,你可以在代码里捕获并打印错误:
function activity_add_instance($data){ global $DB; $data->timecreated = time(); $data->timemodified = time(); $cmid = $data->coursemodule; try { $data->id = $DB->insert_record('testnew', $data); } catch (dml_exception $e) { debugging('插入testnew表失败: ' . $e->getMessage(), DEBUG_DEVELOPER); return false; } // 后续代码... $DB->set_field('course_modules', 'instance', $data->id, ['id' => $cmid]); $data->cmid = $data->coursemodule; return $data->id; }
4. 检查$data对象的完整性
确认$data->coursemodule是否有有效值,有时候插件表单的字段名可能和预期不符,导致$cmid为空,后续的set_field也会失效。可以用var_dump($data)临时打印$data的所有属性,确认关键字段都存在。
5. 验证数据库权限
虽然概率较低,但要确认Moodle使用的数据库账号是否对testnew表有INSERT权限。如果是手动创建的表,可能没有给该账号授权,导致插入失败。
优化后的完整代码示例
结合以上排查点,优化后的代码会更健壮:
function activity_add_instance($data){ global $DB; // 调试:打印$data内容 debugging('准备插入的数据: ' . print_r($data, true), DEBUG_DEVELOPER); $data->timecreated = time(); $data->timemodified = time(); $cmid = isset($data->coursemodule) ? $data->coursemodule : 0; if (empty($cmid)) { debugging('缺少coursemodule ID', DEBUG_DEVELOPER); return false; } try { $data->id = $DB->insert_record('testnew', $data); } catch (dml_exception $e) { debugging('插入失败: ' . $e->getMessage(), DEBUG_DEVELOPER); return false; } if (empty($data->id)) { debugging('插入后未获取到新记录ID', DEBUG_DEVELOPER); return false; } // 更新course_modules的instance字段 $update_result = $DB->set_field('course_modules', 'instance', $data->id, ['id' => $cmid]); if (!$update_result) { debugging('更新course_modules失败,回滚插入记录', DEBUG_DEVELOPER); $DB->delete_records('testnew', ['id' => $data->id]); return false; } $data->cmid = $data->coursemodule; return $data->id; }
开启调试后,你就能快速定位到具体问题,大部分情况都是字段不匹配或者必填字段未赋值导致的。
内容的提问来源于stack exchange,提问作者Aya Ashraf
相关产品推荐
相关产品推荐

