Как обработать Javascript-объект (невалидный JSON) в PHP?

86
06 марта 2021, 04:10

Возникла проблема - API отдаёт данные в JSON формате, примерно в таком виде:

{
  messages: [
    {
      channel: "79991234567",
      phone: "79117777777",
      dateTime: 1544844684000,
      type: 1,
      status: 99,
      text: "Добрый день"
    }, {
      channel: "79991234567",
      phone: "79117777777",
      dateTime: 1544849654000,
      type: 5,
      status: 2,
      text: "",
      content: "https://app.wazzup24.com/api/v1/store/07146d53b21e4a41aca49b6bc2391c7e8100b6dac6df"
    }
  ],
  statuses: [
    {
      messageId: "7271506a-1959-4e39-acaf-2ccc19d77ef2",
      status: 3
    }
  ],
  channels: [
    {
      channel: "79991234567",
      state: "active"
    }
  ]
}

Полученные данные нужно обработать через PHP и я пробовал сделать это через json_decode, но эта функция не возвращала никаких данных. После некоторого поиска и просмотра примеров, я понял, что причина скорее всего в том, что это JS-объект, но он не валиден как JSON, т.к. ключи и некоторые свойства не обёрнуты в кавычки. Можно ли как-то еще решить эту проблему? Заранее спасибо.

Answer 1

ОТВЕТ СОДЕРЖИТ ОШИБКУ

В массивах строками становятся числа (а отрицательные вообще всё ломают), null и true/false.

Если разница по сравнению с json'ом только в том, что часть ключей написаны без кавычек, а всё остальное соответствует формату JSON, то это легко исправляется заменой по регулярному выражению (?:"((?:\\.|.)*)"|([.\w]+))(\s*:\s*(?:[[{]|"(?:\\.|.)*"|[-.\w]+))? на "$1$2"$3.

Вот пример на JS:

var str = document.querySelector('textarea').value 
var json = str.replace(/(?:"((?:\\.|.)*)"|([.\w]+))(\s*:\s*(?:[[{]|"(?:\\.|.)*"|[-.\w]+))?/g, '"$1$2"$3') 
console.log(JSON.parse(json))
.as-console-wrapper.as-console-wrapper { max-height: 100vh }
<textarea>{ 
  messages: [ 
    { 
      channel: "79991234567", 
      phone: "79117777777", 
      dateTime: 1544844684000, 
      type: 1, 
      status: 99, 
      text: "Добрый день" 
    }, { 
      channel: "79991234567", 
      phone: "79117777777", 
      dateTime: 1544849654000, 
      type: 5, 
      status: 2, 
      text: "", 
      content: "https://app.wazzup24.com/api/v1/store/07146d53b21e4a41aca49b6bc2391c7e8100b6dac6df" 
    } 
  ], 
  statuses: [ 
    { 
      messageId: "7271506a-1959-4e39-acaf-2ccc19d77ef2", 
      status: 3 
    } 
  ], 
  channels: [ 
    { 
      channel: "79991234567", 
      state: "active" 
    } 
  ] 
}</textarea>

Answer 2

Проблема решена, всем спасибо за ответы. При дальнейших поисках оказалось, что я был неправ: проблема не в том, что названия не обёрнуты в кавычки, а в том, что, как я узнал, PHP по умолчанию не парсит запросы кроме application/x-www-form-urlencoded multipart/form-data. В моем случае отправлялся запрос application/json и когда я пытался, получить к нему доступ из массива $_POST возвращался пустой массив.

Помогло решение от @E_p (из вопроса Получение данных, отправляемых POST в виде json):

$postData = file_get_contents('php://input');
$data = json_decode($postData, true);

В моем случае это сработало. Еще раз спасибо всем за участие!

READ ALSO
mysql группировка по категории

mysql группировка по категории

есть таблица категории

141
Yii2 проблема с отображением страницы

Yii2 проблема с отображением страницы

Помогите решить вопрос с отображением страницы, не могу понять в чем проблемаИногда страница отображается в таком формате

128
Как заменить /lang=ru на /ru в адресной строке?

Как заменить /lang=ru на /ru в адресной строке?

У меня есть сайт http://wwwexample

117