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