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

Eloquent与DB Facade中toArray()方法行为差异原因及解决办法

差异原因

核心是两种查询返回的集合元素类型不同:

  • 第一段是Eloquent模型查询:User::select()返回的Eloquent\Collection中,每个元素是User模型实例。模型类自带toArray()方法,调用集合的toArray()时,会自动把每个模型实例转换成关联数组,最终得到嵌套数组结构。
  • 第二段是查询构建器查询:DB::table()返回的Support\Collection中,每个元素是原生PHP的stdClass对象。stdClass没有toArray()方法,集合的toArray()仅会把外层集合转为数组,内部的对象会保留原样,所以结果是数组包裹对象。

解决方法

以下三种方法都能让第二段查询返回嵌套数组:

1. 用map()遍历转换每个对象为数组

在集合转数组前,先把每个stdClass对象强制转为数组:

$res2 = DB::connection($destinationDb.'__read')
            ->table("$destinationTable as d")
            ->leftJoin("$soruceDb.$soruceTable as s", "d.".strtolower($configRule['rule']['destination_lookup_key']), '=', "s.".strtolower($configRule['rule']['source_lookup_key']))
            ->select(Db::raw(implode(',',$prefixedSourColumns)))
            ->limit(2)
            ->get()
            ->map(fn($item) => (array)$item) // 转换单个对象为数组
            ->toArray();

2. 直接使用原生查询DB::select()

跳过查询构建器的集合包装,直接返回数组结构:

// 拼接SQL语句
$sql = sprintf(
    "SELECT %s FROM `%s` as d LEFT JOIN `%s`.`%s` as s ON d.%s = s.%s LIMIT 2",
    implode(',',$prefixedSourColumns),
    $destinationTable,
    $soruceDb,
    $soruceTable,
    strtolower($configRule['rule']['destination_lookup_key']),
    strtolower($configRule['rule']['source_lookup_key'])
);

// 执行原生查询,直接得到嵌套数组
$res2 = DB::connection($destinationDb.'__read')->select($sql);

3. 用json_encode()+json_decode()强制转换

利用JSON序列化的特性,把对象集合强制转为数组:

$res2 = DB::connection($destinationDb.'__read')
            ->table("$destinationTable as d")
            ->leftJoin("$soruceDb.$soruceTable as s", "d.".strtolower($configRule['rule']['destination_lookup_key']), '=', "s.".strtolower($configRule['rule']['source_lookup_key']))
            ->select(Db::raw(implode(',',$prefixedSourColumns)))
            ->limit(2)
            ->get()
            ->toArray();

// 强制转换为嵌套数组
$res2 = json_decode(json_encode($res2), true);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 17:04:56