Индекс числового массива теряется при генерировании ответа JSON API - PullRequest
0 голосов
/ 07 июня 2019

Я испытываю непредвиденное поведение с Laravel 5.7 и Php 7.2 при генерации ответа JSON REST API.

Поле в ответе 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.

Мне удалось найти рекурсивный метод filter в Illuminate\Http\Resources\ConditionallyLoadsAttributes класс, который, кажется, очищает любой элемент с помощью цифровой клавиши.Поскольку это часть ядра 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.Это ошибка?Кто-нибудь испытал это и нашел способ?

1 Ответ

0 голосов
/ 07 июня 2019

Благодаря Wiimm!
Решением было использование объекта вместо массива, и индекс был сохранен.Использовал этот довольно не элегантный метод для преобразования из массива в объект json_decode(json_encode($data)), но он работал.

ОБНОВЛЕНИЕ

Проблема была не метод filter в классе Illuminate\Http\Resources\ConditionallyLoadsAttributes, а скорее из-за слияния (с использованием array_merge) непосредственно перед возвратом набора данных.Удаление этой операции перед возвратом массива (больше не объекта) возвращает индекс правильно.

...