Laravel Query Builder结果如何自动转为含子元素的JSON?
Laravel Query Builder 实现扁平结果转嵌套JSON(无需手动解析)
Laravel Query Builder本身没有内置的一键转换方法,但可以借助Laravel集合(Collection)的原生方法,或者结合模型关联的方式,不用手动编写复杂的解析逻辑,就能把扁平查询结果转换成嵌套结构的JSON,完美适配原有Eloquent代码的输出格式,减少迁移工作量。
方法一:利用集合方法重组结构
先通过Query Builder获取扁平结果,再用集合的groupBy和map方法重组嵌套结构:
// 1. 获取扁平查询结果 $flatResults = DB::table('customer_products') ->select('id', 'customer', 'product_id', 'product') ->get(); // 2. 转换为嵌套结构 $nestedData = $flatResults->groupBy('id')->map(function ($group) { $baseInfo = $group->first(); return [ 'id' => $baseInfo->id, 'customer' => $baseInfo->customer, 'products' => $group->map(function ($item) { return [ 'id' => $item->product_id, 'product' => $item->product ]; }) ]; })->values()->first(); // 若需多个客户数据,移除->first()即可 // 3. 转为JSON $jsonOutput = $nestedData->toJson(JSON_PRETTY_PRINT);
执行后得到的JSON结构和你需求的完全一致,无需手动遍历解析。
方法二:结合Eloquent模型关联(迁移成本更低)
如果原有代码基于Eloquent模型,可以将Query Builder的结果hydrate为模型实例,再手动设置关联关系,直接复用原有模型的JSON输出逻辑:
// 假设已有Customer和Product模型 // 1. 提取客户基础数据并转为模型实例 $customers = \App\Models\Customer::hydrate( DB::table('customer_products') ->select('id', 'customer') ->distinct() ->get() ->toArray() ); // 2. 为每个客户设置产品关联 foreach ($customers as $customer) { $customer->setRelation('products', \App\Models\Product::hydrate( DB::table('customer_products') ->where('id', $customer->id) ->select('product_id as id', 'product') ->get() ->toArray() )); } // 3. 直接输出嵌套JSON $jsonOutput = $customers->toJson(JSON_PRETTY_PRINT);
这种方式完全贴合原有Eloquent的关联输出格式,几乎不用修改视图和其他依赖方法。
内容的提问来源于stack exchange,提问作者Ricardo Assis
相关产品推荐
相关产品推荐

