My server receives JSON data from a real-world device, which is then saved in a MySQL JSON field. Unfortunately, the manufacturer seems to have a bug in their code which causes part of the data to be stringified escaped JSON.
[
"foo",
"bar",
"info",
{
"data": "{"parts":[{"id":1,"serial":"19777","type":"NONE","key":""}]}",
"vendor": "Test",
"message": "Hello world"
}
]
Running json_decode
even with JSON_UNESCAPED_SLASHES
results in a string
Array
(
[0] => foo
[1] => bar
[2] => info
[3] => Array
(
[data] => {"parts":[{"id":1,"serial":"19777","type":"NONE","key":""}]}
[vendor] => Test
[message] => Hello world
)
)
But the expected output is
Array
(
[0] => foo
[1] => bar
[2] => info
[3] => Array
(
[data] => Array
(
[parts] => Array
(
[0] => Array
(
[id] => 1
[serial] => 19777
[type] => NONE
[key] =>
)
)
)
[vendor] => Test
[message] => Hellow world
)
)
Since I cannot expect them to release a firmware update any time soon, is there any function I can run on the entire JSON to identify stringified JSON and re-encode the request before saving to MySQL, but not effect other messages that do not have a similar bug?
Advertisement
Answer
Update: turn any nested json data inside $json
into associative array:
Recurse through array $arr
using function recurse()
, to find any elements with json data and json_decode()
them to arrive at your expected output:
<?php
$arr = json_decode($json, true);
recurse($arr); // json_decode() any json inside $arr
function recurse(array &$arr)
{
foreach ($arr as $key => &$value) {
if (is_array($value)) {
recurse($value);
} else {
if (is_object(json_decode($value))) {
$value = json_decode($value, true); // turn json into assoc array
}
}
}
}
working demo