PHPackages                             icecave/duct - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. icecave/duct

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

icecave/duct
============

An incremental streaming JSON parser.

2.0.2(11y ago)763.5k1[1 issues](https://github.com/icecave/duct/issues)1MITPHPPHP &gt;=5.4

Since May 3Pushed 7y ago6 watchersCompare

[ Source](https://github.com/icecave/duct)[ Packagist](https://packagist.org/packages/icecave/duct)[ Docs](https://github.com/IcecaveStudios/duct)[ RSS](/packages/icecave-duct/feed)WikiDiscussions master Synced 3w ago

READMEChangelog (9)Dependencies (4)Versions (10)Used By (1)

Duct
====

[](#duct)

[![Build Status](https://camo.githubusercontent.com/74a543659b9d5688f0662b07c6c5c32e316c683a16a770b6b8ca722a62d53fb2/687474703a2f2f696d672e736869656c64732e696f2f7472617669732f696365636176652f647563742f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/icecave/duct)[![Code Coverage](https://camo.githubusercontent.com/17bfd22fd7cc4e32fadf6337b7c450f744819c3757cddc4ad71d6967b7a89992/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f696365636176652f647563742f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://codecov.io/github/icecave/duct)[![Latest Version](https://camo.githubusercontent.com/0f76385970018d8d27e6788426bf3a598a48f17c10234a6eec2d3703c0b54e26/687474703a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f696365636176652f647563742e7376673f7374796c653d666c61742d737175617265266c6162656c3d73656d766572)](https://semver.org)

**Duct** is a PHP library for incrementally parsing continuous streams of JSON values.

```
composer require icecave/duct

```

**Duct** is designed to parse sequential JSON values from data streams, without framing or demarcation outside of the JSON specification.

Examples
--------

[](#examples)

### Simple parsing

[](#simple-parsing)

**Duct** can be used to parse multiple JSON documents in a single call to `Parser::parse()`. The JSON string given must contain complete values.

```
use Icecave\Duct\Parser;

$parser = new Parser;
$values = $parser->parse('[ 1, 2, 3 ] [ 4, 5, 6 ]');

assert($values[0] === [1, 2, 3]);
assert($values[1] === [4, 5, 6]);
```

### Incremental parsing

[](#incremental-parsing)

Asynchronous, incremental parsing is also possible using the `Parser::feed()`, `values()` and `finalize()` methods.

```
use Icecave\Duct\Parser;

$parser = new Parser;

// JSON data can be fed to the parser incrementally.
$parser->feed('[ 1, ');

// An array of completed values can be retreived using the values() method.
// At this point no complete object has been parsed so the array is empty.
$values = $parser->values();
assert(0 === count($values));

// As more data is fed to the parser, we now have one value available, an array
// of elements 1, 2, 3.
$parser->feed('2, 3 ][ 4, 5');
$values = $parser->values();
assert(1 === count($values));
assert($values[0] == [1, 2, 3]);

// Note that calling values() is destructive, in that any complete objects are
// removed from the parser and will not be returned by future calls to values().
$values = $parser->values();
assert(0 === count($values));

// Finally we feed the remaining part of the second object to the parser and the
// second value becomes available.
$parser->feed(', 6 ]');
$values = $parser->values();
assert(1 === count($values));
assert($values[0] == [4, 5, 6]);

// At the end of the JSON stream, finalize is called to parse any data remaining
// in the buffer. An exception is thrown if the buffer contains an incomplete
// value.
$parser->finalize();

// In this case there were no additional values.
$values = $parser->values();
assert(0 === count($values));
```

### Event-based parsing

[](#event-based-parsing)

**Duct** also provides `EventedParser`, an event-based incremental parser similar to the [Clarinet](https://github.com/dscape/clarinet)library for JavaScript. Event management is provided by [Événement](https://github.com/igorw/evenement), a popular PHP event library.

As per the example above the `feed()` and `finalize()` methods are used, however there is no `values()` method. Instead, the following events are emitted as the buffer is parsed.

- **document-open**: emitted when a JSON document is begun
- **document-close**: emitted after an entire JSON document has been parsed
- **array-open**: emitted when an array open bracket is encountered
- **array-close**: emitted when an array closing bracket is encountered
- **object-open**: emitted when an object open brace is encountered
- **object-close**: emitted when an object closing brace is encountered
- **object-key** (string $key): emitted when an object key is encountered
- **value** (mixed $value): emitted whenever a scalar or null is encountered, including inside objects and arrays
- **error** (Exception $error): emitted when a syntax error is encountered

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity32

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 99.1% 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 ~90 days

Recently: every ~110 days

Total

9

Last Release

4081d ago

Major Versions

0.4.0 → 1.0.02014-09-30

1.0.0 → 2.0.02014-12-24

PHP version history (2 changes)0.1.0PHP &gt;=5.3

2.0.0PHP &gt;=5.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/93a71bd75fcd51efee464532dbdd54927cd00e938805998c76e0a804d38fa3fb?d=identicon)[jmalloc](/maintainers/jmalloc)

---

Top Contributors

[![jmalloc](https://avatars.githubusercontent.com/u/761536?v=4)](https://github.com/jmalloc "jmalloc (105 commits)")[![koden-km](https://avatars.githubusercontent.com/u/1037307?v=4)](https://github.com/koden-km "koden-km (1 commits)")

---

Tags

streamjsoneventparserparsereactevented

### Embed Badge

![Health badge](/badges/icecave-duct/health.svg)

```
[![Health](https://phpackages.com/badges/icecave-duct/health.svg)](https://phpackages.com/packages/icecave-duct)
```

###  Alternatives

[react/stream

Event-driven readable and writable streams for non-blocking I/O in ReactPHP

691139.1M205](/packages/react-stream)[kigkonsult/icalcreator

iCalcreator is the PHP implementation of rfc2445/rfc5545 and rfc updates, management of calendar information

2462.8M20](/packages/kigkonsult-icalcreator)[cerbero/lazy-json

Framework-agnostic package to load JSONs of any dimension and from any source into Laravel lazy collections.

255316.2k1](/packages/cerbero-lazy-json)[rodenastyle/stream-parser

PHP Multiformat Streaming Parser

447202.3k2](/packages/rodenastyle-stream-parser)[mkraemer/react-pcntl

PCNTL bindings for ReactPHP

57290.1k9](/packages/mkraemer-react-pcntl)[mkraemer/react-inotify

Inotify bindings for ReactPHP

4616.3k1](/packages/mkraemer-react-inotify)

PHPackages © 2026

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