1

I can't figure out how to create a multi-level JSON output using PHP and MySQL.

I have this query (simplified for this question)

$query = "SELECT 
           1 as id, 
           JSON_OBJECT('key1', 1, 'key2', 'abc') as json1";

which I turn into an array

while ($row = mysqli_fetch_assoc($result)) {
        $resultArray[] = $row;
}
return $resultArray;

and then use json_encode:

echo json_encode($result);

This gets me

[
    {
        id: "1",
        json1: "{"key1": 1, "key2": "abc"}"
    }
]

i.e., the variable is returned as a string.

What I would like to achieve is to have the variable json_test as a second level of JSON, like so:

[
    {
        id: "1",
        json1: 
                  {
                       key1: 1, 
                       key2: "abc"
                  }
    }
]

I have tried following hints around this site, but no joy:

JSON_ARRAY(GROUP_CONCAT(JSON_OBJECT('key1', 1, 'key2', 'abc'))) AS json2

gives me

json2: "["{\"key1\": 1, \"key2\": \"abc\"}"]",

and

CAST(CONCAT('[',GROUP_CONCAT(JSON_OBJECT('key1', 1, 'key2', 'abc')),']') AS JSON) AS json3

gives me

json3: "[{"key1": 1, "key2": "abc"}]"

Any hints are greatly appreciated.

I'm on PHP 7.0.25 and MySQL 5.7.20.

2 Answers 2

1

The JSON_OBJECT is returned to PHP as a string (as prodigitalson commented)

You want to have all your data as an associative array.

In order to do that, in the example you posted, json1 must be passed thru json_decode.

while ($row = mysqli_fetch_assoc($result)) {
        $row['json1'] = json_decode( $row['json1'], true ); // <----
        $resultArray[] = $row;
}
return $resultArray;

Now you should get the desired result:

echo json_encode($resultArray);
Sign up to request clarification or add additional context in comments.

Comments

0

Building the desired structure with MySQL can be done like this:

mysql> SELECT JSON_OBJECT('id', 1, 'json1', JSON_OBJECT('key1', 1, 'key2', 'abc')) AS obj;
+------------------------------------------------+
| obj                                            |
+------------------------------------------------+
| {"id": 1, "json1": {"key1": 1, "key2": "abc"}} |
+------------------------------------------------+
1 row in set (0.00 sec)

And in PHP, we can either go from JSON to array:

php > var_dump(json_decode('{"id":1,"json1":{"key1":1,"key2":"abc"}}', TRUE));
array(2) {
  ["id"]=>
  int(1)
  ["json1"]=>
  array(2) {
    ["key1"]=>
    int(1)
    ["key2"]=>
    string(3) "abc"
  }
}

Or array to JSON:

php > $tmp = ['id' => 1, 'json1' => ['key1' => 1, 'key2' => 'abc']];
php > var_dump($tmp);
array(2) {
  ["id"]=>
  int(1)
  ["json1"]=>
  array(2) {
    ["key1"]=>
    int(1)
    ["key2"]=>
    string(3) "abc"
  }
}
php > print(json_encode($tmp));
{"id":1,"json1":{"key1":1,"key2":"abc"}}

7 Comments

Thanks for your answer! Unfortunately, your suggestion doesn't seem to work - this is what I get: [ { obj: "{"id": 1, "json1": {"key1": 1, "key2": "abc"}}" } ]
As you can see, I copied and pasted directly from command-line PHP and MySQL. What are your needs that are not yet met?
What are you running, and what are the desired results?
You're currently putting in in an object as a string. If you use json_decode to make it into an object, then you can put it in as a key and re-encode the whole thing. If you supply your code I can show you how this would look
mysqli will not cast a JSON_OBJECT to a php array or stdObject. you need to call json_decode in your loop if you want to re-encode for output.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.