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
相关产品推荐
相关产品推荐

