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

Laravel Resource单资源返回时关联数组转为索引数组问题咨询

问题原因

这个问题由Laravel 8的资源序列化逻辑差异和PHP的JSON编码默认行为共同导致:

  1. 你用(object)[]初始化的associations是stdClass类型,添加整数键属性时,PHP会将属性存储为整数索引。
  2. 单资源返回时,JsonResource会在序列化前递归将stdClass转换为关联数组,你的associations转数组后结构为[2 => ['suppliers' => [], 'offices' => []]],后续Laravel的响应处理会自动将非连续整数键的数组重排为从0开始的索引数组,导致原始整数键丢失。
  3. 资源集合返回时,ResourceCollection的序列化逻辑不会对单条资源内的stdClass做强制转数组处理,因此原始的整数键对象结构会被保留。
可用解决方案
  • 方案1:强制associations保留对象结构
    直接用关联数组存储结构,返回前通过JSON编码强制转换为不会被重排的对象,该方案兼容性最好,不会影响其他字段的序列化:

    $arr = ['id' => $this->id, 'associations' => []];
    foreach ($tas as $ta) {
        $ta_id = $ta->id;
        $arr['associations'][$ta_id] = ['suppliers' => [], 'offices' => []];
    }
    // 强制转换为对象,避免键被重排
    $arr['associations'] = json_decode(json_encode($arr['associations'], JSON_FORCE_OBJECT));
    return $arr;
    
  • 方案2:修改单资源响应编码参数
    重写Resource类的toResponse方法,为响应添加JSON_FORCE_OBJECT编码参数:

    public function toResponse($request)
    {
        return response()->json($this->resolve($request), 200, [], JSON_FORCE_OBJECT);
    }
    

    注意:该方案会将响应内所有索引数组转为对象,若响应中存在正常的索引数组不建议使用。

  • 方案3:添加占位字符串键
    在associations中添加一个字符串类型的占位键,让JSON编码自动识别为关联对象,不会重排整数键,实现最简单:

    $arr['associations'] = ['_' => null]; // 前端可直接忽略该占位字段
    foreach ($tas as $ta) {
        $ta_id = $ta->id;
        $arr['associations'][$ta_id] = ['suppliers' => [], 'offices' => []];
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:48:04