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

使用PHP数组展示MySQL表时触发‘Trying to get property of non-object’错误求助

解决PHP中获取MySQL数据时的「Trying to get property of non-object」错误

首先,核心问题出在你使用的$DB->get_record_sql()方法上——这个方法只返回单条匹配的记录对象,但你的SQL是分组查询,显然会返回多条结果。当你用foreach去遍历这个单个对象时,你实际上是在遍历对象的属性(比如date、unique_visitor这些字段值),而不是多条记录。此时循环里的$record变成了字符串或数字类型的属性值,自然没法用$record->date这种对象属性访问方式,直接触发了错误。

快速修复步骤

1. 替换方法获取多条记录

把获取数据的方法从get_record_sql改成复数形式的get_records_sql——这个方法会返回一个包含多条记录对象的数组,刚好适配你的foreach遍历逻辑:

// 注意这里改成get_records_sql(复数)
$records = $DB->get_records_sql($sql, null);

2. 验证修改后的完整代码片段

调整后的核心代码如下,其余表格配置部分不变:

$records = $DB->get_records_sql($sql, null);
//create the table
$table->define_columns(array('date', 'unique_visitor', 'viewed', 'created', 'restored'));
$table->define_headers(array('Date', 'Unique Visitor', 'Viewed', 'Created', 'Restored'));
$table->set_attribute('class', 'generaltable generalbox boxaligncenter boxwidthwide table-bordered');
$table->show_download_buttons_at(array(TABLE_P_BOTTOM));
$table->setup();
print_r($records) . "<br><br>";
if ($records) {
    foreach ($records as $record) {
        $row = array();
        $row[] = $record->date;
        $row[] = $record->unique_visitor;
        $row[] = $record->viewed;
        $row[] = $record->created;
        $row[] = $record->restored;
        $table->add_data($row);
    }
}
$table->finish_output();

3. 关键安全优化:避免SQL注入

你的当前SQL直接拼接$courseId、$startDateU等变量,存在严重的SQL注入风险。建议用参数绑定的方式,把变量作为第二个参数传入方法(这也是Moodle DB类的标准用法):

// 用?作为占位符代替直接拼接变量
$sql = "SELECT DATE(FROM_UNIXTIME(timecreated)) AS date, COUNT(DISTINCT userid) AS unique_visitor, SUM(IF (action = 'viewed', 1,0)) AS viewed, SUM(IF (action = 'created', 1,0)) AS created, SUM(IF (action = 'restored', 1,0)) AS restored FROM `table_name` WHERE `courseid` = ? AND (`timecreated` BETWEEN ? AND ?) GROUP BY DATE(FROM_UNIXTIME(timecreated))";
// 把变量放入数组作为第二个参数传入
$records = $DB->get_records_sql($sql, array($courseId, $startDateU, $endDateU));

额外说明

你之前用print_r($records)看到的单个对象,就是get_record_sql返回的单条记录,这也能解释为什么遍历会出错。改成get_records_sql后,print_r会输出一个包含多个对象的数组,此时foreach就能正确遍历每一条记录,表格也能正常渲染数据了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:57:49