Как я могу кодировать только первый уровень в JSON с вложенным объектом PHP - PullRequest
0 голосов
/ 05 апреля 2020

Моя среда - Cake PHP 3.8, но это базовый c вопрос, который необязательно указывает Cake c.

Фон:

* 1006 Допустим, у нас есть вложенный объект. На первом уровне есть статьи, на втором уровне комментарии. В статьях нужны комментарии для определенных расчетов (например, для количества комментариев в статье или для расчета рейтинга). Комментарии не следует отправлять в браузер (как JSON).

Поэтому мне нужен только первый уровень (статьи) в структуре JSON.

json_encode отображает завершить PHP структуру в JSON объекте (включая комментарии). Существует параметр depth, но он указывает, когда json_encode не удалось, а не когда json_encode должен прекратиться.

Есть ли способ преобразовать только первый уровень объекта PHP в JSON?

Конечно, я знаю, что это кажется каким-то странным, потому что «комментарии» - это ключ на первом уровне. Может быть, есть способ отобразить только скалярные типы в JSON.

1-е изменение

Возможно, я объяснил это слишком поверхностно.

В моем Контроллер тортов:

$erticles = $ this->Articles->find ('all', ['contain' => ['Comments']]);
$this->set ('articles', $ articles);
$this->set ('_serialize', ['articles']);
$this->viewBuilder()->setClassName ('Json');

$articles теперь является resultSet объектом, но это не важно, поскольку его можно повторять. Допустим, это массив.

a

var_dump ($articles->toArray()) 

будет выглядеть так:

array(2) { 
  [0]=> object(App\Model\Entity\Article)#7749 (5) { 
    ["id"]=> int(66040)
    ["name"]=> string(5) "Test1" 
    ["comments"]=> array(2) { 
      [0]=> object(App\Model\Entity\Entity)#7749 (2) {
        ["id"]=> int(66041)
        ["comments"]=> string(8) "Comment1" 
      }
      [1]=> object(App\Model\Entity\Entity)#7749 (2) {
        ["id"]=> int(66042)
        ["comments"]=> string(8) "Comment1" 
      }
    }
    ["count_comments"]=> 2 
    ["created"]=> "2018-10-10 20:29:13.000000" 
  }
  [1]=> object(App\Model\Entity\Article)#7749 (5) { 
    ["id"]=> int(66043)
    ["name"]=> string(5) "Test2" 
    ["comments"]=> array(2) { 
      [0]=> object(App\Model\Entity\Entity)#7749 (3) {
        ["id"]=> int(66044)
        ["comments"]=> string(8) "Comment3" 
      }
      [1]=> object(App\Model\Entity\Entity)#7749 (2) {
        ["id"]=> int(66045)
        ["comments"]=> string(8) "Comment4" 
      }
      [2]=> object(App\Model\Entity\Entity)#7749 (2) {
        ["id"]=> int(66046)
        ["comments"]=> string(8) "Comment5" 
      }
    }
    ["count_comments"]=> 3 
    ["created"]=> "2018-10-10 20:29:13.000000" 
  }
}

(Это всего лишь пример, который я набрал вручную. предназначен для разъяснения фактов. Я не могу отобразить исходную структуру, потому что она слишком велика, и приложение содержит не два, а 5 уровней. Проблема (и решение) будут одинаковыми.

@ Nick: Спасибо за быстрый комментарий, итерация и удаление объекта не является решением, потому что некоторые свойства являются виртуальными. Это означает, что когда я обращаюсь к count_comments, комментарии подсчитываются, поэтому они все еще должны существовать в время создания первого уровня.

В результате я sh:

[
   {
      "id":66040,
      "name":"Test1",
      "count_comments":2,
      "created":"2018-10-10 20:29:13.000000"
   },
   {
      "id":66043,
      "name":"Test2",
      "count_comments":3,
      "created":"2018-10-10 20:29:13.000000"
   }
]

Надеюсь, я мог бы express себя немного более четко теперь

1 Ответ

0 голосов
/ 05 апреля 2020

Я не совсем уверен, если это то, что вы хотите? Я хотел бы попытаться создать новый массив на основе вашего исходного массива и на этом вновь созданном массиве - сделайте json_encode.

Примерно так ...

<?php
$first_level_arr = array();
foreach($articles->toArray() as $arr) {
    $first_level_arr[] = array(
                            $arr['id'], 
                            $arr['name'], 
                            $arr['count_comments'], 
                            $arr['created']
                         );
}

$result_json = json_encode($first_level_arr);

Если вы не t эти кнопки c (выше), вы можете использовать array_keys. (но тогда вы получите ВСЕ ключи на первом уровне (включая ключ комментариев)).

foreach($articles->toArray() as $key=>$arr) {
    $include_keys = array_keys($arr);
    foreach($include_keys as $firstlevel_key) {
        $first_level_arr[$key][$firstlevel_key] = $arr[$firstlevel_key];
    }
}

//If you want to remove a specific key you could do like this:
//(In this case removal of the comments key)
foreach($first_level_arr as &$fla) {
    unset($fla['comments']);
}

$result_json = json_encode($first_level_arr);
...