PHPackages                             klkvsk/json-decode-stream - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. klkvsk/json-decode-stream

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

klkvsk/json-decode-stream
=========================

JSON streaming reader

v1.0.3(4y ago)458.7k↓30.4%3[1 issues](https://github.com/klkvsk/json-decode-stream/issues)[2 PRs](https://github.com/klkvsk/json-decode-stream/pulls)1MITPHPPHP &gt;=7.1

Since Dec 6Pushed 3y ago1 watchersCompare

[ Source](https://github.com/klkvsk/json-decode-stream)[ Packagist](https://packagist.org/packages/klkvsk/json-decode-stream)[ Docs](https://github.com/klkvsk/json-decode-stream)[ RSS](/packages/klkvsk-json-decode-stream/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (5)Dependencies (4)Versions (6)Used By (1)

json-decode-stream
==================

[](#json-decode-stream)

[![Min PHP version](https://camo.githubusercontent.com/6c29e60023aae668c1eb4b8d0ce84c548bef384886d141c7e1e9249b5e874938/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6b6c6b76736b2f6a736f6e2d6465636f64652d73747265616d)](https://camo.githubusercontent.com/6c29e60023aae668c1eb4b8d0ce84c548bef384886d141c7e1e9249b5e874938/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6b6c6b76736b2f6a736f6e2d6465636f64652d73747265616d)[![Build Status](https://github.com/klkvsk/json-decode-stream/workflows/Tests/badge.svg)](https://github.com/klkvsk/json-decode-stream/actions)[![Scrutinizer tests](https://camo.githubusercontent.com/7d78f842b729f1b9b6b42a82debeb4f744205653ada40cd4aa8ed6bd27a3ac1b/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f6275696c642f672f6b6c6b76736b2f6a736f6e2d6465636f64652d73747265616d3f6c6162656c3d7363727574696e697a6572)](https://scrutinizer-ci.com/g/klkvsk/json-decode-stream/inspections)[![Scrutinizer coverage](https://camo.githubusercontent.com/cd9e864280a656ac799b728a082d7f4d1ee6e376c4d61ad87458abbbe91c22e2/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f6b6c6b76736b2f6a736f6e2d6465636f64652d73747265616d)](https://scrutinizer-ci.com/g/klkvsk/json-decode-stream/code-structure/master/code-coverage/src/)[![Scrutinizer code quality](https://camo.githubusercontent.com/fc9da959ea5213b9b2ab51b77f3e785195fafdda1e6b5808f3081ee0a8b80c78/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f7175616c6974792f672f6b6c6b76736b2f6a736f6e2d6465636f64652d73747265616d)](https://scrutinizer-ci.com/g/klkvsk/json-decode-stream/reports/)[![Packagist version](https://camo.githubusercontent.com/9b99e0293882c9189c931beccf8c985cfbffa3136f0e6dba77050f9f09f3a713/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6b6c6b76736b2f6a736f6e2d6465636f64652d73747265616d)](https://packagist.org/packages/klkvsk/json-decode-stream)

This is a JSON parsing library that allows parsing stream of JSON data. You can process JSON records on the fly without decoding complete structure into memory first. This is especially useful when parsing large JSON files.

Installation
------------

[](#installation)

```
composer require klkvsk/json-decode-stream
```

Basic usage
-----------

[](#basic-usage)

In most cases, streaming parser is used to parse lists of repeated objects. For example, here is a list of users:

```
{
  "users": [
    { "name": "Alice", "age": 20 },
    { "name": "Bob", "age": 30 }
  ]
}
```

To iterate over each user and print their name, use:

```
$parser = \JsonDecodeStream\Parser::fromFile("users.json");
foreach ($parser->items("users[]") as $user) {
    echo $user->name;
}
// or
foreach ($parser->items("users[].name") as $name) {
    echo $name;
}
```

Documentation
-------------

[](#documentation)

**json-decode-stream** uses layered generators to process data. There are 3 layers, and the processing goes as follows:

```
Tokenizer -(tokens)-> Parser -(events)-> Collector -(items)-> your code

```

- **Tokens** are parts of encoded JSON data: braces, comas, strings, numbers.
- **Events** are emitted based on sequence of incoming tokens: object started/ended, key specified, value, etc.
- **Items** are final parts of decoded JSON: scalar values, arrays and objects, that are matched by **selectors**.

`Parser` class provides access to each layer directly, but for most use cases only `$parser->items($selector)` is needed.

### Selectors

[](#selectors)

Selector is a string that specifies full path to collected JSON fields. Simple selectors are:

- `[]` - any element of an array or every key of an object
- `[5]` - element of an array with index 5
- `[10:15]` - any element of an array with index ranged from 10 to 15
- `[5:]` - any element of an array starting from index 5
- `[:5]` - any element of an array before and including index 5
- `foo` - value of an object by key 'foo'
- `["some long key with spaces or \"quotes\" in it"]` - also a value by key

Selectors can be nested:

- `users[]` would select each user
- `result.total` would select key "total" in "result" object
- `result[]` would select value of "total" and any other fields of "result" object
- `users[:2].name` would select names of first 3 users
- `[].id` would select every ID in the top-level array of objects with "id" field

### Reference

[](#reference)

#### Parser

[](#parser)

Constructors:

- `Parser::fromString($jsonString)`
- `Parser::fromFile($filePath)`
- `Parser::fromStream($resource)`

    Where `$resource` is any resource that supports `fread()`
- `Parser::fromPsr7($stream)`

    Where `$stream` is any PSR-7 compliant StreamInterface, i.e. `$psr7Request->getBody()`
- `new Parser(new SourceBuffer(new SourceInterfaceImplementation()))`

    Use in other custom cases

Methods:

- `$parser->tokens(): Generator`

    Iterates over encoded JSON document, returning `Token` objects.
- `$parser->events(): Generator`

    Iterates over `tokens()`, returning `Event` objects.
- `$parser->items($selectors): Generator`

    Iterates over `events()`, returning decoded JSON fields matched by selectors

    Where`$selectors` either

    - single selector string: `"result.users[]"`
    - coma-separated selector strings: `"result.total, result.users[]"`
    - array of selector strings: `[ "result.total", "result.users[]" ]`
    - custom CollectorInterface or array of them
    - `null` to collect whole objects/arrays in JSON-sequences (separated with coma or/and newline in source)

    String selectors are converted to `Collector` classes internally.

    For default Collector, iterated values have their full path in key, like `"result.users[4]" => ["num" => "Five", ..]`

#### Event

[](#event)

Methods:

- `$event->getId(): string`

    Enumeration:

    - `Event::DOCUMENT_START`
    - `Event::DOCUMENT_END`
    - `Event::OBJECT_START`
    - `Event::OBJECT_END`
    - `Event::KEY`
    - `Event::VALUE`
- `$event->getValue(): string|number|bool|null`

    - For `Event::VALUE` a corresponding value is returned.
    - For `Event::KEY` a string (field name of an object) is returned.
    - For other events null is returned.
- `$event->getPath(): string`

    Full path to the currently parsed element.
- `$event->getDepth(): int`

    How many nested levels of JSON structure are we deep. Elements of top-level array/object have depth 1.
- `$event->matchPath(string $selector): bool`

    Checks if currenly parsed element's path is contained within selector.
- `$event->getLineNumber(): int` and `$event->getCharNumber(): int`

    Returns currently parsed position inside decoded source.

#### Token

[](#token)

- `$token->getId(): string`

    Enumeration:

    - `Token::OBJECT_START`
    - `Token::OBJECT_END`
    - `Token::ARRAY_START`
    - `Token::ARRAY_END`
    - `Token::KEY_DELIMITER`
    - `Token::COMA`
    - `Token::TRUE`
    - `Token::FALSE`
    - `Token::NULL`
    - `Token::STRING`
    - `Token::NUMBER`
    - `Token::WHITESPACE`
- `$token->getValue(): string|number|bool|null`

    Returns corresponding value only for `STRING`, `NUMBER` or `WHITESPACE` tokens.
- `$token->getLineNumber(): int` and `$token->getCharNumber(): int`

    Returns currently parsed position inside decoded source.

#### Custom Collectors

[](#custom-collectors)

`CollectorInterface` defines only one method:

- `processEvent(Event $event)`

Return an array of `[ key, value ]` to be yielded from `items()` when you need to emit an item.

Yield multiple `[ key, value ]`s when you need to emit multiple items.

Otherwise, return null if you have nothing yet to yield.

Here is an example of custom Collector:

```
class AggregationCollector implements CollectorInterface
{
    protected int $count;
    protected float $sum;

    public function processEvent(Event $event)
    {
        switch ($event->getId()) {
            case Event::DOCUMENT_START:
                $this->count = 0;
                $this->sum = 0;
                break;

            case Event::VALUE:
                if ($event->matchPath("games[].score")) {
                    $this->sum += $event->getValue();
                    $this->count++;
                }
                break;

            case Event::DOCUMENT:END:
                yield [ 'count', $this->count ];
                yield [ 'sum', $this->sum ];
                yield [ 'avg', $this->count ? ($this->sum / $this->count) : 0 ];
                break;
        }
    }
}

$aggregates = iterator_to_array($parser->items(new AggregationCollector()));
var_dump($aggregates); // [ 'count' => 10, 'sum' => 50, 'avg' => 5 ]
```

Dependencies
------------

[](#dependencies)

There are no external dependencies except `ext-json`, which is normally comes with every PHP distribution.

Default `json_decode` is used to parse single JSON strings when Parser finds them. This is faster and more error-proof than writing own JSON string parser/validator.

Testing
-------

[](#testing)

This lib is heavily [covered](https://scrutinizer-ci.com/g/klkvsk/json-decode-stream/code-structure/master/code-coverage/src/)with unit tests and [CI-tested](https://github.com/klkvsk/json-decode-stream/actions) under all versions of PHP since 7.1.

To run tests, install via composer with `--dev` and run

```
$ vendor/bin/phpunit
```

License
-------

[](#license)

This code is distributed under [MIT license](./LICENSE.txt).

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance15

Infrequent updates — may be unmaintained

Popularity35

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~51 days

Total

5

Last Release

1784d ago

Major Versions

v0.0.1 → v1.0.02020-12-07

### Community

Maintainers

![](https://www.gravatar.com/avatar/e8c39df33c0429a10cb82630098652f9761d78b94244d749b9b3aa2627865249?d=identicon)[klkvsk](/maintainers/klkvsk)

---

Top Contributors

[![klkvsk](https://avatars.githubusercontent.com/u/1466771?v=4)](https://github.com/klkvsk "klkvsk (46 commits)")

---

Tags

streamjsondecodeparse

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/klkvsk-json-decode-stream/health.svg)

```
[![Health](https://phpackages.com/badges/klkvsk-json-decode-stream/health.svg)](https://phpackages.com/packages/klkvsk-json-decode-stream)
```

###  Alternatives

[kherge/json

Encodes, decodes, and validates JSON data.

61226.6k6](/packages/kherge-json)[symfony/json-streamer

Provides powerful methods to read/write data structures from/into JSON streams.

14440.0k8](/packages/symfony-json-streamer)[janeklb/json-char-input-reader

Read a JSON stream and execute callbacks whenever complete JSON chunks are parsed

2450.0k](/packages/janeklb-json-char-input-reader)[cerbero/json-objects

Extract objects from large JSON files, endpoints or streams while saving memory.

2229.3k](/packages/cerbero-json-objects)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
