PHPackages                             maxi-format/maxi - 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. maxi-format/maxi

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

maxi-format/maxi
================

PHP library for parsing and dumping MAXI format

0.5.0(2w ago)127↓100%MITPHPPHP &gt;=8.0CI passing

Since May 12Pushed 2w agoCompare

[ Source](https://github.com/maxi-format/maxi-php)[ Packagist](https://packagist.org/packages/maxi-format/maxi)[ RSS](/packages/maxi-format-maxi/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (5)Dependencies (3)Versions (6)Used By (0)

maxi-php
========

[](#maxi-php)

PHP 8.0+ library for parsing and dumping **MAXI schema + records**.

Install
-------

[](#install)

```
composer require maxi-format/maxi
```

API overview
------------

[](#api-overview)

MethodDescription`Maxi::parse($input, $options)`Parse MAXI text → `MaxiParseResult` (schema + raw records)`Maxi::stream($input, $options)`Parse schema eagerly, yield records lazily via PHP generator`Maxi::parseAs($input, $classMap, $options)`Parse + hydrate records into class instances`Maxi::parseAutoAs($input, $classes, $options)`Same, with alias inferred from `#[MaxiType]` attributes`Maxi::dump($data, $options)`Serialize objects / parse results → MAXI text`Maxi::dumpAuto($objects, $options)`Same, with schema inferred from `#[MaxiType]`/`#[MaxiField]` attributesAll methods are also available as standalone functions in the `Maxi\Api` namespace (e.g. `Maxi\Api\parseMaxi()`).

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

[](#documentation)

- **[docs/parser.md](docs/parser.md)** — full parser guide: `Maxi::parse`, `Maxi::stream`, `Maxi::parseAs`, `Maxi::parseAutoAs`, hydration, reference resolution, options
- **[docs/dumper.md](docs/dumper.md)** — full dumper guide: `Maxi::dump`, `Maxi::dumpAuto`, schema-annotated classes, references, inheritance, options

Quick start
-----------

[](#quick-start)

### Parse

[](#parse)

```
use Maxi\Maxi;

$input = schema->getType('U')->name; // 'User'
```

### Parse into class instances

[](#parse-into-class-instances)

```
use Maxi\Maxi;
use Maxi\Attribute\MaxiType;
use Maxi\Attribute\MaxiField;

#[MaxiType(alias: 'U', name: 'User')]
class User
{
    #[MaxiField(typeExpr: 'int', id: true)]
    public int $id;

    #[MaxiField(required: true)]
    public string $name;

    #[MaxiField(annotation: 'email')]
    public ?string $email = null;
}

$result = Maxi::parseAutoAs($input, [User::class]);

$user = $result->data['U'][0];
echo $user->name;  // 'Julie'
echo $user->email; // 'julie@maxi.org'
```

Or with an explicit alias → class map:

```
$result = Maxi::parseAs($input, ['U' => User::class]);
```

### Dump

[](#dump)

Round-trip from a parse result:

```
$maxi = Maxi::dump($result);
```

From PHP objects with auto-detected schema:

```
$maxi = Maxi::dumpAuto([
    new User(id: 1, name: 'Julie', email: 'julie@maxi.org'),
]);
```

With explicit type definitions:

```
use function Maxi\Api\dumpMaxi;

$maxi = dumpMaxi([['id' => 1, 'name' => 'Julie']], [
    'defaultAlias' => 'U',
    'types' => [[
        'alias'  => 'U',
        'name'   => 'User',
        'fields' => [
            ['name' => 'id', 'typeExpr' => 'int'],
            ['name' => 'name'],
        ],
    ]],
]);
```

### Stream (lazy record parsing)

[](#stream-lazy-record-parsing)

For large files, use streaming to avoid loading all records into memory at once. The schema is parsed eagerly; records are yielded one at a time via a PHP generator:

```
$stream = Maxi::stream($input);

echo $stream->schema->getType('U')->name; // 'User'

foreach ($stream as $record) {
    echo $record->alias;     // 'U'
    echo $record->values[1]; // field values
}
```

`stream()` also accepts a file handle (`resource`):

```
$fh     = fopen('data.maxi', 'r');
$stream = Maxi::stream($fh);
```

PHP Attributes — Doctrine-style annotations
-------------------------------------------

[](#php-attributes--doctrine-style-annotations)

Map MAXI types to PHP classes using native PHP 8 Attributes:

```
use Maxi\Attribute\MaxiType;
use Maxi\Attribute\MaxiField;

#[MaxiType(alias: 'O', name: 'Order')]
class Order
{
    #[MaxiField(typeExpr: 'int', id: true)]
    public int $id;

    #[MaxiField(typeExpr: 'U')]
    public int|User $user;

    #[MaxiField(typeExpr: 'decimal')]
    public string $total;
}
```

`MaxiField` supports the following options:

OptionTypeDescription`typeExpr``?string`MAXI type expression (`'int'`, `'str[]'`, `'enum[a,b]'`, `'U'`)`annotation``?string`Type annotation (`'email'`, `'base64'`, `'hex'`)`required``bool`Adds the `!` (required) constraint`id``bool`Marks this field as the record identifier`defaultValue``mixed`Default value when field is omitted`name``?string`Override the serialized field name (defaults to property name)`constraints``?string`Raw constraint string (e.g. `'>=3, 'U',
    'name'   => 'User',
    'fields' => [
        ['name' => 'id',    'typeExpr' => 'int', 'constraints' => [['type' => 'id']]],
        ['name' => 'name'],
        ['name' => 'email', 'annotation' => 'email'],
    ],
]);
```

Error handling
--------------

[](#error-handling)

All parse/dump errors throw `Maxi\Core\MaxiException` which carries structured context:

```
use Maxi\Core\MaxiException;

try {
    Maxi::parse($input, ['allowTypeCoercion' => 'error']);
} catch (MaxiException $e) {
    echo $e->errorCode;    // e.g. 'E402'
    echo $e->maxiLine;     // line number where the error occurred
    echo $e->maxiFilename; // filename (if provided via options)
    echo $e->getMessage(); // human-readable description
}
```

### Error codes

[](#error-codes)

CodeNameDescriptionE101InvalidSyntaxErrorGeneral syntax errorE102DuplicateTypeErrorDuplicate type alias in schemaE103UnknownDirectiveErrorUnrecognised `@directive`E201UnknownTypeErrorRecord uses undefined type aliasE202UndefinedParentErrorParent type not definedE203CircularInheritanceErrorCircular type inheritanceE204UnresolvedReferenceErrorReference ID not foundE205DuplicateIdentifierErrorDuplicate id in recordsE301ConstraintSyntaxErrorMalformed constraintE302InvalidConstraintValueErrorInvalid constraint valueE303ConstraintViolationErrorValue violates a constraintE304ArraySyntaxErrorMalformed array literalE401SchemaMismatchErrorToo many/few values for typeE402TypeMismatchErrorValue doesn't match field typeE403MissingRequiredFieldErrorRequired field is null/missingE404InvalidDefaultValueErrorDefault value type mismatchE405UnsupportedBinaryFormatErrorInvalid bytes annotationE501EnumAliasErrorDuplicate or ambiguous enum aliasE601UnsupportedVersionError`@version` value not supportedE602SchemaLoadErrorError loading external schemaE603StreamErrorError during streaming parse### Parser behavior options

[](#parser-behavior-options)

By default, the parser **warns** on type mismatches, missing fields, and constraint violations instead of throwing. Tune this per option:

```
// Warn on type mismatches (default)
$result = Maxi::parse($input);

foreach ($result->warnings as $w) {
    echo "[{$w->code}] {$w->message} (line {$w->line})\n";
}
```

To make any of these fatal, set the relevant option to `'error'`:

```
// Throw on type mismatches
$result = Maxi::parse($input, ['allowTypeCoercion' => 'error']);

// Throw on any schema violation
$result = Maxi::parse($input, [
    'allowTypeCoercion'         => 'error',
    'allowMissingFields'        => 'error',
    'allowAdditionalFields'     => 'error',
    'allowConstraintViolations' => 'error',
]);
```

External schema imports
-----------------------

[](#external-schema-imports)

MAXI files can import type definitions from external `.mxs` schema files. Provide a `loadSchema` callback to resolve them:

```
$result = Maxi::parse($input, [
    'loadSchema' => function (string $path): string {
        return file_get_contents(__DIR__ . '/schemas/' . $path);
    },
]);
```

MAXI format (quick reference)
-----------------------------

[](#maxi-format-quick-reference)

```
U:User(id:int|name|email=unknown)   ← type definition
###                                 ← section separator
U(1|Julie|~)                        ← record  (~ = explicit null)

```

- Omitted trailing fields use their declared default value.
- `~` sets a field to explicit `null`, even if it has a default.
- Arrays: `[1,2,3]` — Maps: `{key:value,key2:value2}`
- Inline objects: `O(100|(1|Julie|julie@maxi.org)|99.99)`
- See the [MAXI spec](../maxi/SPEC.md) for the full format definition.

Test
----

[](#test)

```
composer test
```

License
-------

[](#license)

Released under the [MIT License](./LICENSE).

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance96

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity32

Early-stage or recently created project

 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 ~2 days

Total

5

Last Release

19d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/11738128?v=4)[Max Beckers](/maintainers/maxbeckers)[@maxbeckers](https://github.com/maxbeckers)

---

Top Contributors

[![maxbeckers](https://avatars.githubusercontent.com/u/11738128?v=4)](https://github.com/maxbeckers "maxbeckers (13 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/maxi-format-maxi/health.svg)

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

###  Alternatives

[mck89/peast

Peast is PHP library that generates AST for JavaScript code

19037.7M41](/packages/mck89-peast)[karriere/json-decoder

JsonDecoder implementation that allows you to convert your JSON data into PHP class objects

141439.4k12](/packages/karriere-json-decoder)[sauladam/shipment-tracker

Parses tracking information for several carriers, like UPS, USPS, DHL and GLS by simply scraping the data. No need for any kind of API access.

9642.0k](/packages/sauladam-shipment-tracker)[jstewmc/rtf

Read and write Rich Text Format (RTF) documents with PHP

45143.1k6](/packages/jstewmc-rtf)[json-mapper/laravel-package

The JsonMapper package for Laravel

25188.9k3](/packages/json-mapper-laravel-package)[jamesmoss/toml

A parser for TOML implemented in PHP.

3231.7k15](/packages/jamesmoss-toml)

PHPackages © 2026

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