Получить значения из массива JSON в PHP в следующем формате?

Я получил этот массив от разработчика Android, с которым я работаю, и мне нужно получить значения ключа name из следующего массива:

[ 
   { 
      "data":"[{\"name\":\"step 1 kdfhghdkgjdf\\nkjdhfgkjhdkjghd\\nkdfjhgkjdhfg\\n\\n\\ndfjhgkjdfjhgdfgd\\n\"},{\"name\":\"step 2 dhfgkjdfhkhkjchjkfd\\ndkjhjdf\\njhkdfhkghdkfhgkdhg\\n\\n\\ndfjhgkjdfhgdfhgkjdhfgkjhdf\"},{\"name\":\"step 3 kkkkkkkkkk\"},{\"name\":\"step 4 ljlejrhlflhgf\\n\\n\\ndfhjk\"}]",
      "status":1
   }
]

Я попытался сделать следующее:

 <?php
    $s = '[
  {
    "data": "[{\"name\":\"step 1 kdfhghdkgjdf\\nkjdhfgkjhdkjghd\\nkdfjhgkjdhfg\\n\\n\\ndfjhgkjdfjhgdfgd\\n\"},{\"name\":\"step 2 dhfgkjdfhkhkjchjkfd\\ndkjhjdf\\njhkdfhkghdkfhgkdhg\\n\\n\\ndfjhgkjdfhgdfhgkjdhfgkjhdf\"},{\"name\":\"step 3 kkkkkkkkkk\"},{\"name\":\"step 4 ljlejrhlflhgf\\n\\n\\ndfhjk\"}]",
    "status": 1
  }
]';
    $obj = json_decode($s,true);
    echo $obj[0]['data']
    ?> 

Что дает мне следующий вывод:

[
  {
    "name": "step 1 kdfhghdkgjdf kjdhfgkjhdkjghd kdfjhgkjdhfg dfjhgkjdfjhgdfgd "
  },
  {
    "name": "step 2 dhfgkjdfhkhkjchjkfd dkjhjdf jhkdfhkghdkfhgkdhg dfjhgkjdfhgdfhgkjdhfgkjhdf"
  },
  {
    "name": "step 3 kkkkkkkkkk"
  },
  {
    "name": "step 4 ljlejrhlflhgf dfhjk"
  }
]

Но мне нужны только значения ключа name, например:

step 1 kdfhghdkgjdf kjdhfgkjhdkjghd kdfjhgkjdhfg dfjhgkjdfjhgdfgd
step 2 dhfgkjdfhkhkjchjkfd dkjhjdf jhkdfhkghdkfhgkdhg dfjhgkjdfhgdfhgkjdhfgkjhdf
step 3 kkkkkkkkkk
.
.
.

Мой вопрос похож на этот: Получить значение из массива JSON в PHP Только формат другой.

Можно ли получить значения в этом формате? Если да, то как? Если нет, неверный ли формат?


person Shubham    schedule 25.09.2019    source источник
comment
Скажите разработчику Android, чтобы он снова правильно предоставил данные json. Это, конечно, действительный JSON, но он выглядит как JSON внутри JSON. Я говорю это, потому что он/она делает вещи излишне сложными на стороне сервера.   -  person nice_dev    schedule 25.09.2019
comment
Что вы имеете в виду, что хотите получить значения ключа name? Будет ли достаточно массива, в котором каждый индекс является одной из этих строк?   -  person Blake Morgan    schedule 25.09.2019
comment
Большая часть проблемы здесь заключается в том, что (некоторые) данные закодированы дважды. Это должно быть исправлено приложением, отправляющим данные. Это не работа сервера, чтобы решать такие проблемы. Заставьте их отправлять один связный объект JSON, а не этот глупый формат JSON-внутри-JSON.   -  person ADyson    schedule 25.09.2019
comment
@vivek_23 Я обновил вопрос. Пожалуйста, проверьте вопрос еще раз.   -  person Shubham    schedule 25.09.2019
comment
@Shubham данные в обновленной части точно такие же, как и вверху. Какая разница?   -  person AterLux    schedule 25.09.2019
comment
@BlakeMorgan Я просто хочу, чтобы значения внутри массива с ключом name его имя могло быть чем-то вроде xyz или abc. Мне не нужно имя ключа. Я хочу его значение.   -  person Shubham    schedule 25.09.2019
comment
@AterLux ранее был отформатирован. Таким образом, двойная обратная косая черта была преобразована в одинарную обратную косую черту.   -  person Shubham    schedule 25.09.2019
comment
Даже после редактирования основная мысль остается в силе. Данные по-прежнему представляют собой JSON-внутри-JSON, и их по-прежнему необходимо исправлять в источнике, чтобы сделать все это одним единым объектом, чтобы с ним было просто и предсказуемо работать. Поговорите со своим разработчиком Android и объясните ситуацию.   -  person ADyson    schedule 25.09.2019
comment
@ADyson решит ли проблему удаление скобок [ ] из строки (начало и конец) с конца разработчика?   -  person Shubham    schedule 25.09.2019
comment
Нет. Не перекодировать эту информацию как отдельный бит JSON, а затем добавить ее во внешний раздел, как будто это строка, которая решит ее. Здесь вы фактически получили объект JSON, в котором есть данные свойства. Это свойство содержит строку. Поэтому, когда вы выбираете свой JSON, вы получаете строку. Содержимое этой строки выглядит как JSON, за исключением того, что добавлены некоторые дополнительные escape-символы для работы с кавычками внутри строки.   -  person ADyson    schedule 25.09.2019
comment
Я предполагаю, что ваш разработчик Android кодирует список имен в виде строки JSON. Затем он устанавливает эту строку как свойство другого объекта. Наконец, он кодирует этот второй объект как JSON и отправляет его вам. Это приводит к экранированию/двойному кодированию исходной строки JSON. Что ему нужно сделать, так это создать один единственный объект, содержащий все данные, а затем закодировать весь этот объект в JSON за один шаг. Это создаст разумный объект JSON, который он может отправить вам.   -  person ADyson    schedule 25.09.2019


Ответы (2)


Во-первых, внутри поля "data" у вас не json-структура, а просто строка, содержащая json-данные.

Поэтому вы сделали это неправильно, когда преобразовали данные в постоянное значение. Сначала вы должны удвоить все обратные косые черты.

Затем вы можете получить элемент "data" и выполнить json_decode еще раз.

<?php
    $s = '[
  {
    "data": "[{\\"name\\":\\"step 1 kdfhghdkgjdf\\\\nkjdhfgkjhdkjghd\\\\nkdfjhgkjdhfg\\\\n\\\\n\\\\ndfjhgkjdfjhgdfgd\\\\n\\"},{\\"name\\":\\"step 2 dhfgkjdfhkhkjchjkfd\\\\ndkjhjdf\\\\njhkdfhkghdkfhgkdhg\\\\n\\\\n\\\\ndfjhgkjdfhgdfhgkjdhfgkjhdf\\"},{\\"name\\":\\"step 3 kkkkkkkkkk\\"},{\\"name\\":\\"step 4 ljlejrhlflhgf\\\\n\\\\n\\\\ndfhjk\\"}]",
    "status": 1
  }
]';
    $obj = json_decode($s,true);
    $data = json_decode($obj[0]['data'], true);

    foreach($data as $item) {
      print($item['name'] . "\r\n");
    }
person AterLux    schedule 25.09.2019
comment
Я разместил отформатированный JSON, пожалуйста, проверьте вопрос еще раз. Я отредактировал вопрос. - person Shubham; 25.09.2019
comment
@Shubham, это не меняет моего ответа. Когда вы помещаете косую черту в строковую константу в php, вы должны экранировать их, добавляя косую черту. - person AterLux; 25.09.2019
comment
Коды внутри ответа не дают никакого результата! - person Shubham; 25.09.2019
comment
Он выводит каждый элемент имени. Только что еще раз проверил. Не забудьте префикс <?php - person AterLux; 25.09.2019
comment
@MaroofMandal да, это так. Демонстрация: sandbox.onlinephpfunctions.com/code/ . однако было бы в целом лучше, если бы данные были в разумном формате, когда они были отправлены - person ADyson; 25.09.2019
comment
Чтобы сделать это таким образом, вы должны использовать addslashes вместо того, чтобы добавлять их вручную. - person AbraCadaver; 25.09.2019

Предполагая, что $obj[0]['data'] действительно имеет опубликованный вами JSON, просто декодируйте и извлеките столбцы name:

foreach(array_column(json_decode($obj[0]['data'], true), 'name') as $name) {
    echo $name;
}
person AbraCadaver    schedule 25.09.2019
comment
Да... хотя ИМХО было бы лучше, чтобы данные отправлялись как один объект для начала - person ADyson; 25.09.2019