violet-php / streaming-json-encoder

PHP library for iteratively encoding large JSON documents piece by piece
http://violet.riimu.net
MIT License
314 stars 16 forks source link

Complex JSON output? #1

Closed baohx2000 closed 7 years ago

baohx2000 commented 7 years ago

Not an issue, but a request for an example.

Before I start testing with it, is it possible for your JSON stream library to create more complex objects? For example, I have a generator which will give arrays to output, but they go in a subsection of the response json:

{
 "@count": 37,
 "@data": [
   {
     "id": 1,
     "name": "bob"
   },
   ...more items
 ]
}

My generator only creates the items which go under @data. Can you give an example of how this could be done? Or is it as easy as just passing in another buffer encoder as a value to the top level encoder?

I'll probably play with this later today. If you have time to answer, that would help a lot.

Riimu commented 7 years ago

The library essentially recurses through the entire value. In other words, let's say you provide an array that contains a closure that produces a generator. That iterators in sub arrays/values will be iterated in the same way. For example:

<?php

require 'vendor/autoload.php';

$objects = [
    '1:foo',
    '2:bar',
    '4:baz',
];

$data = [
    '@count' => count($objects),
    '@data' => function () use ($objects) {
        foreach ($objects as $string) {
            $parsed = explode(':', $string);
            yield [
                'id' => $parsed[0],
                'name' => $parsed[1],
            ];
        }
    },
];

$encoder = new \Violet\StreamingJsonEncoder\BufferJsonEncoder($data);
$encoder->setOptions(JSON_PRETTY_PRINT);
echo $encoder->encode();

This would produce a JSON document like:

{
    "@count": 3,
    "@data": [
        {
            "id": "1",
            "name": "foo"
        },
        {
            "id": "2",
            "name": "bar"
        },
        {
            "id": "4",
            "name": "baz"
        }
    ]
}

Does that answer your question?

baohx2000 commented 7 years ago

Yes, thank you!