
当使用laravel的db::select()执行原生sql查询(如对接clickhouse)时,返回的是关联数组而非对象,直接用箭头语法(→)访问字段会触发“attempt to read property on array”错误,应改用数组下标语法访问。
当使用laravel的db::select()执行原生sql查询(如对接clickhouse)时,返回的是关联数组而非对象,直接用箭头语法(→)访问字段会触发“attempt to read property on array”错误,应改用数组下标语法访问。
在Laravel中,DB::select() 方法(无论是否指定连接如 DB::connection('clickhouse'))始终返回 PHP关联数组组成的索引数组(即 array<array mixed>></array>),而非Eloquent模型或标准stdClass对象。因此,即使SQL字段名符合驼峰或下划线规范,也不能使用 $value->id_tahun 这样的对象属性访问方式——PHP会抛出 Attempt to read property "id_tahun" on array 的致命错误。
✅ 正确写法如下(使用方括号语法访问数组键):
$factpelanggan = DB::connection('clickhouse')
->select('SELECT id_tahun, t.tahun, l.id_lokasi
FROM dim_tahun t, dim_lokasi l');
$id_tahun = [];
$id_lokasi = [];
$tahun = [];
foreach ($factpelanggan as $value) {
$id_tahun[] = $value['id_tahun']; // ✅ 正确:数组键访问
$id_lokasi[] = $value['id_lokasi']; // ✅ 注意键名需与SELECT中别名/原始列名完全一致
$tahun[] = $value['tahun']; // ✅ 若SQL中为 t.tahun,则键名为 'tahun'(非 't.tahun')
}⚠️ 注意事项:
- 键名严格区分大小写,且不包含表别名前缀(如
t.tahun在结果中仅映射为'tahun',除非显式使用AS别名); - 若SQL中存在同名列(如多表JOIN含重复字段),建议始终使用
AS显式别名避免歧义,例如:t.tahun AS tahun_year→ 访问$value['tahun_year']; - 如需转为对象便于链式调用,可手动转换:
(object) $value,但不推荐——既增加开销,又违背Laravel原生查询的设计约定; - 若需Eloquent风格操作,应考虑封装ClickHouse数据源为自定义模型(配合
Model::unguarded()和protected $connection = 'clickhouse'),但需注意Eloquent默认不支持ClickHouse语法特性(如嵌套类型、部分聚合函数)。
总结:牢记 DB::select() 返回数组,而非对象;统一使用 $row['column_name'] 访问字段,是规避此类错误最直接、最可靠的方式。


















