Skip to content

Commit b01a3e4

Browse files
committed
Clarify object resolution in README
1 parent d66afbe commit b01a3e4

File tree

1 file changed

+37
-26
lines changed

1 file changed

+37
-26
lines changed

README.md

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -221,32 +221,43 @@ documentation](http://www.php-fig.org/psr/psr-7/#psrhttpmessagestreaminterface).
221221

222222
### How the encoder resolves values ###
223223

224-
Since Streaming JSON Encoder only handles values one at a time and tries to
225-
avoid loading entire data sets into memory at once, there are several
226-
fundamental differences to how this library handles values compared to
227-
`json_encode`.
228-
229-
To determine whether any given value should be encoded as an object or as an
230-
array, the encoder makes the following decisions:
231-
232-
* Only arrays that have keys from 0 to n-1 in that order are encoded as JSON
233-
arrays. All other arrays are encoded as objects.
234-
* Any object is encoded as a JSON array if the key of the first value
235-
returned by iterating over the object equals to `0`. All other objects are
236-
encoded as JSON objects.
237-
238-
Additionally, prior to the decision whether to encode an object as an array or
239-
as an object is made, the encoder will attempt to resolve the value as follows:
240-
241-
* As long as the processed value is a `JsonSerializable`, the encoder will
242-
replace the processed value with the return value of the `jsonSerialize()`
243-
method.
244-
* As long as the processed value is a `Closure`, it will be replaced with the
245-
value returned by invoking the closure.
246-
247-
Note that it's possible to override the decision between an array or an object
248-
by using the `JSON_FORCE_OBJECT` option, which will force all objects and arrays
249-
to be encoded as JSON objects.
224+
In many ways, the Streaming JSON encoder is intended to work mostly as a drop in
225+
replacement for `json_encode()`. However, since the encoder is intended to deal
226+
with large data sets, there are some notable differences in how it handles
227+
objects and arrays.
228+
229+
First, to determine how to encode an object, the encoder will attempt to resolve
230+
the object values in following ways:
231+
232+
* For any object that implements `JsonSerializable` the implemented method
233+
`jsonSerialize()` is called and return value is used instead.
234+
* Any `Closure` will be invoked and the return value will be used instead.
235+
However, no other invokables are called in this manner.
236+
237+
The returned value is looped until it cannot be resolved further. After that,
238+
a decision is made on whether the array or object is encoded as an array or as
239+
an object. The following logic is used:
240+
241+
* Any empty array or array that has keys from 0 to n-1 in that order are
242+
encoded as JSON arrays. All other arrays are encoded as JSON objects.
243+
* If an object implements `Traversable` and it either returns an **interger**
244+
`0` as the first key or returns no values at all, it will be encoded as a
245+
JSON array (regardless of other keys). All other objects implementing
246+
`Traversable` are encoded as JSON objects.
247+
* Any other object, whether it's empty or whatever keys it mey have, is encoded
248+
as a JSON object.
249+
250+
Note, however, that if the JSON encoding option `JSON_FORCE_OBJECT` is used, all
251+
objects and arrays are encoded as JSON objects.
252+
253+
Note that all objects are traversed via a `foreach` statement. This means that
254+
all `Traversable` objects are encoded using the values returned by the iterator.
255+
For other objects, this means that the public properties are used (as per
256+
default iteration behavior).
257+
258+
All other values (i.e. nulls, booleans, numbers and strings) are treated exactly
259+
the same way as `json_encode()` does (and in fact, it's used to encode those
260+
values).
250261

251262
### JSON encoding options ###
252263

0 commit comments

Comments
 (0)