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

Laravel 5.6如何让API资源支持自定义数组键?

解决Laravel 5.6 API资源保留自定义数组键的问题

这个问题我太熟悉了——Laravel 5.6的API资源集合默认会偷偷把自定义数组键重置成索引序列(比如你遇到的把1变成0),哪怕你用了withoutWrapping()也没用,因为那个方法只管移除最外层的data包裹,根本管不了内部集合对数组键的自动转换。

要保住你的自定义键,核心就是绕过默认的collection()方法,手动构建带原键的关联数组,具体步骤如下:

1. 为子资源创建单独的资源类

先给access_control里的单个条目创建资源类,比如AccessControlItemResource:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class AccessControlItemResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'allowed' => $this->allowed,
            // 这里可以添加其他需要返回的字段
        ];
    }
}

2. 在父资源中手动构建带自定义键的数组

在你的主资源类(比如EntryResource)里,不要用collection()方法处理access_control,而是通过遍历手动保留原键:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class EntryResource extends JsonResource
{
    public function toArray($request)
    {
        // 手动遍历access_control,完整保留原键
        $accessControl = [];
        foreach ($this->access_control as $key => $item) {
            $accessControl[$key] = new AccessControlItemResource($item);
        }

        return [
            'status' => 'success',
            'entry' => [
                'access_control' => $accessControl,
            ],
        ];
    }
}

3. 控制器中返回资源

在控制器里直接返回这个主资源即可,全局的Resource::withoutWrapping()设置不会影响这里的自定义键:

public function show($id)
{
    $entry = \App\Entry::findOrFail($id);
    return new EntryResource($entry);
}

为什么默认会丢失键?

Laravel的Resource::collection()方法返回的是ResourceCollection实例,它内部会把传入的集合转换成索引数组,自动重置所有键。所以只要你用了这个方法处理带自定义键的数组,键就会被强制覆盖。手动遍历构建数组就能完美避开这个默认行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:57:17