生成 JSON API 响应后,数字数组索引丢失
Posted
技术标签:
【中文标题】生成 JSON API 响应后,数字数组索引丢失【英文标题】:Numeric array index lost once JSON API response is generated 【发布时间】:2019-10-22 09:55:53 【问题描述】:在生成 JSON REST API 响应时,我在使用 Laravel 5.7 和 php 7.2 时遇到了意外行为。
API 响应中的字段包含一个以数字索引但按如下值排序的数组:
"selections" => array:3 [▼
3 => "Barton & Guestier/ Spirit/ Brian"
1 => "Barton & Guestier/ Wine/ Latour"
2 => "Dom Pérignon/ Effervescent/ Champagne"
]
一旦字段被Illuminate\Http\Resources\Json\JsonResource
类处理以进行编码,索引将从 JSON 输出中剥离,并且数组作为顺序数组返回,如下所示:
"selections": [
"Barton & Guestier/ Spirit/ Brian",
"Barton & Guestier/ Wine/ Latour",
"Dom Pérignon/ Effervescent/ Champagne"
],
如果数组是这样按键排序的,则相同
"selections" => array:3 [▼
1 => "Barton & Guestier/ Wine/ Latour"
2 => "Dom Pérignon/ Effervescent/ Champagne"
3 => "Barton & Guestier/ Spirit/ Brian"
变成了
"selections": [
"Barton & Guestier/ Wine/ Latour",
"Dom Pérignon/ Effervescent/ Champagne"
"Barton & Guestier/ Spirit/ Brian",
],
第一项的索引不再索引3
或1
,而是0
。
问题是我需要保留这些索引,因为它们对应于我的 SQL 数据库中这些条目的 ID。
我能够在Illuminate\Http\Resources\ConditionallyLoadsAttributes
类中找到递归方法filter
,它似乎正在使用数字键清除任何元素。
由于它是 Laravel 核心的一部分,因此我无法更改此方法。
/**
* Filter the given data, removing any optional values.
*
* @param array $data
* @return array
*/
protected function filter($data)
$index = -1;
$numericKeys = array_values($data) === $data;
foreach ($data as $key => $value)
$index++;
if (is_array($value))
$data[$key] = $this->filter($value);
continue;
if (is_numeric($key) && $value instanceof MergeValue)
return $this->mergeData($data, $index, $this->filter($value->data), $numericKeys);
if ($value instanceof self && is_null($value->resource))
$data[$key] = null;
return $this->removeMissingValues($data, $numericKeys);
当然,我不是第一个尝试返回具有特定顺序或不从索引 0
开始的数值数组的人。这是一个错误吗?
有没有人经历过这种情况并找到解决方法?
【问题讨论】:
无法复制问题3v4l.org/D9u5s 在 JSON/javascript 中,数组只是一个没有明确索引的元素列表。如果需要索引,请使用对象。 另一种解决方案:使用带有元素的数组,其中每个元素是一对[index,value]。 Wiimm 这确实是我正在做的事情(索引 => 值)。问题是 SQL 数据库生成的数值中的索引。您使用对象而不是数组的想法成功了!感谢您为我指明这个方向。 【参考方案1】:感谢 Wiimm!
使用对象而不是数组是解决方案,并且保留了索引。
使用这种相当不优雅的方法将数组转换为对象json_decode(json_encode($data))
,但它确实有效。
更新
问题不是Illuminate\Http\Resources\ConditionallyLoadsAttributes
类中的filter
方法,而是因为在返回数据集之前合并(使用array_merge
)。在返回数组(不再是对象)之前删除此操作会正确返回索引。
【讨论】:
以上是关于生成 JSON API 响应后,数字数组索引丢失的主要内容,如果未能解决你的问题,请参考以下文章