Laravel - почему json ответ возвращает иногда массив, иногда объект - PullRequest
1 голос
/ 10 января 2020

Вот мой код:

    public function list()
    {
        $users = User::with('group')->get()->toArray();
        return response()->json([

            'clients' => array_filter($users, function ($r) {
                return $r['group']['name'] === 'client';
            }),

            'employes' => array(array_filter($users, function ($r) {
                return $r['group']['name'] !== 'client';
            })),

        ]);
    }

Вот ответ:

{
  "clients": {
    "2": {
      "id": 3,
      "name": "Client 1",
      "email": "client@a.fr",
      "email_verified_at": null,
      "created_at": null,
      "updated_at": null,
      "group_id": 4,
      "group": {
        "id": 4,
        "name": "client"
      }
    },
    "3": {
      "id": 4,
      "name": "Client 2",
      "email": "client2@a.fr",
      "email_verified_at": null,
      "created_at": null,
      "updated_at": null,
      "group_id": 4,
      "group": {
        "id": 4,
        "name": "client"
      }
    },
    "4": {
      "id": 5,
      "name": "Client 3",
      "email": "client3@a.fr",
      "email_verified_at": null,
      "created_at": null,
      "updated_at": null,
      "group_id": 4,
      "group": {
        "id": 4,
        "name": "client"
      }
    }
  },
  "employes": [
    [
      {
        "id": 1,
        "name": "Alexis",
        "email": "alexis@a.fr",
        "email_verified_at": null,
        "created_at": null,
        "updated_at": null,
        "group_id": 1,
        "group": {
          "id": 1,
          "name": "admin"
        }
      },
      {
        "id": 2,
        "name": "guest",
        "email": "guest@a.fr",
        "email_verified_at": null,
        "created_at": null,
        "updated_at": null,
        "group_id": 2,
        "group": {
          "id": 2,
          "name": "guest"
        }
      }
    ]
  ]
}

Я пытался изменить условия array_filter. Иногда у меня есть массив, иногда у меня есть объект. Я не понимаю, как это определяется

Stackoverflow говорит мне: «Похоже, ваш пост в основном кодовый; пожалуйста, добавьте еще немного деталей». Итак ... какие детали добавить?

Спасибо

1 Ответ

2 голосов
/ 10 января 2020

Внутренне array_filter() фильтрует совпадающие записи из массива и возвращает их с неизменными их индексами . Это очень важно, так как это основная причина, по которой вы получаете object, а не array в JavaScript.

в PHP, это нормально; Массивы могут начинаться с 0 или другого индекса, такого как 2, и функционировать как массив без проблем. Это связано с существованием массивов indexed (на основе 0) и associative (на основе числовых / ненулевых c ключей).

В JavaScript массивы не могут быть "ассоциативными" то есть они должны начинаться с 0. object классы, с другой стороны, функционируют аналогично ассоциативным массивам, но ключевое отличие состоит в том, что они не являются явно массивами.

Теперь, когда вы знаете причину, следующий вопрос "как мне это исправить?" Простой способ - обернуть array_filter() функцией, которая просто возвращает значения нового массива. Это по своей сути «переиндексирует» массив значениями, основанными на 0, что при преобразовании в JSON приведет к возвращению правильных массивов:

$users = User::with('group')->get()->toArray();

$clients = array_filter($users, function($r){
  return $r['group']['name'] === 'client';
});

$groups = array_filter($users, function ($r) {
  return $r['group']['name'] !== 'client';
});

return response()->json([
  'clients' => array_values($clients),
  'groups' => array_values($groups)
]);

В качестве идентификатора классы Collection имеют аналогичные logi c, и я предпочитаю использовать Laravel Collection класс, когда это возможно:

$users = User::with('group')->get();

$clients = $users->filter(function($r){
  $r->group->name === 'client';
});

$groups = $users->filter(function($r){
  $r->group->name !== 'client';
});

return response()->json([
  'clients' => $clients->values(),
  'groups' => $groups->values()
]);

Но опять же, это мое предпочтение; Любой подход должен работать, поэтому используйте то, к чему вы привыкли.

Ссылки:

PHP Методы массива:

https://www.php.net/manual/en/function.array-filter.php

https://www.php.net/manual/en/function.array-values.php

Laravel Методы сбора:

https://laravel.com/docs/5.8/collections#method -фильтр

https://laravel.com/docs/5.8/collections#method -значения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...