Features | Why JsonFast | Performance | API | Quick Start | Install via Package | Building | Docker | Testing | Benchmarks
php_jsonfast is a PHP extension written in Rust that provides fast JSON parsing, repair, formatting, path access, schema validation, merge/diff, and flexible output modes — returning native PHP arrays, JSON strings, or stdClass objects.
✔ Repair malformed JSON (comments, JSONP, trailing commas, and more)
✔ Dot-path and wildcard path access
✔ Beautify, minify, merge, and diff
✔ Schema inference, validation, and application
✔ Flexible output: array, string, or object
✔ Built on serde_json with order-preserving object keys
- Repair broken JSON from real-world sources (JavaScript literals, JSONP wrappers, BOM, comments)
- Analyse invalid JSON and get suggested repair flags before fixing
- Format JSON with configurable indentation or compact minification
- Path access with dot notation and wildcards (
user.name,users[*].email) - Transform documents with deep merge and structural diff
- Schema infer, validate, apply defaults, and diff schemas
- Output modes on every data-returning method: PHP array (default), JSON string, or
stdClassobject
Most PHP JSON workflows combine json_decode(), manual array walking, and third-party libraries for repair and schema validation. php_jsonfast consolidates these into a single Rust-backed extension:
- One API for parse, repair, format, path, merge, diff, and schema operations
- Repair logic for common non-standard JSON (not supported by
json_decode()) - Path queries without decoding the full document into PHP first
- Schema validation without pulling in a separate Composer dependency
- Consistent output mode control across all methods
- Lower overhead on large payloads compared to multi-step PHP pipelines
Benchmarks were run on synthetic JSON payloads in Docker (
php:8.3-cli-bookworm). Results depend on hardware, payload size, PHP version, and runtime environment. These figures are project-level reference numbers, not universal guarantees.
Run benchmarks locally:
make benchmark
# custom run: iterations, medium payload items, max capacity items
make benchmark BENCH_ITERATIONS=1000 BENCH_ITEMS=500 BENCH_CAPACITY=200000| Operation | Implementation | Ops/sec |
|---|---|---|
| Diff | Native PHP | ~170 |
| Diff | JsonFast | ~570 |
| Schema validation | opis/json-schema | ~100 |
| Schema validation | justinrainbow/json-schema | ~50 |
| Schema validation | JsonFast | ~920 |
JsonFast diff is roughly 3.3× faster than the native PHP helper in this benchmark. Schema validation is roughly 9× faster than Opis and 18× faster than JustinRainbow on the medium test document.
Measured on a ~32 MB broken/repairable JSON payload (200k items):
| Operation | Throughput |
|---|---|
| Repair | ~33 MB/sec |
| Merge | ~46 MB/sec |
| Diff | ~38 MB/sec |
Capacity benchmark from 1k → 200k items (mean time, ms):
| Items | Repair | Merge | Diff |
|---|---|---|---|
| 1,000 | ~5 | ~2 | ~3 |
| 50,000 | ~250 | ~160 | ~210 |
| 100,000 | ~590 | ~320 | ~420 |
| 200,000 | ~1,060 | ~700 | ~850 |
All three operations scale roughly linearly with document size in this test.
The benchmark suite compares JsonFast against native PHP and popular libraries where applicable:
| Category | Compared against |
|---|---|
| Repair | JsonFast throughput (files/sec, MB/sec) |
| Encode / beautify / minify | json_encode() |
| Path access | json_decode() + manual traversal |
| Merge / diff | Native PHP helpers |
| Schema validation | opis/json-schema, justinrainbow/json-schema |
Reported metrics:
| Metric | Description |
|---|---|
| Ops/sec | Operations completed per second |
| Mean / P95 | Average and 95th percentile latency (ms) |
| Files/sec | Repair throughput by document count |
| MB/sec | Repair throughput by input payload size |
| Peak memory | Peak allocated memory during benchmark |
| Large JSON capacity | Scaling test from 1k → 200k nested records |
View the full docs here
All methods are static. Data-returning methods accept an optional $output argument.
| Constant | Value | Returns |
|---|---|---|
JsonFast::OUTPUT_ARRAY |
0 |
PHP array (default) |
JsonFast::OUTPUT_STRING |
1 |
Compact or formatted JSON string |
JsonFast::OUTPUT_OBJECT |
2 |
stdClass for JSON objects |
| Constant | Description |
|---|---|
REPAIR_BOM |
Strip UTF-8 byte order mark |
REPAIR_JSONP |
Strip JSONP wrapper (callback(...)) |
REPAIR_COMMENTS |
Remove // and /* */ comments |
REPAIR_TRAILING_COMMAS |
Remove trailing commas |
REPAIR_DOUBLE_ENCODED |
Unwrap double-encoded JSON strings |
REPAIR_UNQUOTED_STRINGS |
Quote unquoted string values |
REPAIR_SINGLE_QUOTES |
Convert single quotes to double quotes |
REPAIR_UNQUOTED_KEYS |
Quote unquoted object keys |
REPAIR_ALL |
All repair flags combined |
Returns true if the input is valid JSON.
Repairs malformed JSON using the specified flag bitmask.
$fixed = JsonFast::repair($broken, JsonFast::REPAIR_ALL, JsonFast::OUTPUT_STRING);Analyses JSON and returns validity, error location, and suggested repair flags.
Example return value (array output):
[
'valid' => false,
'repairable' => true,
'error' => [
'message' => '...',
'line' => 3,
'column' => 18,
],
'repairs' => [
[
'flag' => 'REPAIR_COMMENTS',
'bit' => 4,
'description' => 'Removes // and /* */ comments',
],
],
]Pretty-prints JSON with the given indent width.
Minifies JSON to a compact string or parsed PHP value.
Returns validation status with error line/column for invalid JSON.
Recursively unwraps double-encoded JSON strings up to $maxDepth.
Reads a value at a dot/bracket path. Returns null if the path does not exist.
Supported path syntax:
user.nameusers[0].emailusers[*].email(viasearch())
Returns true if the path exists in the document.
Collects all values matching a wildcard path.
$emails = JsonFast::search($json, 'users[*].email');
// ['allan@example.com', 'bob@example.com']Extracts multiple paths into a single object/map.
$result = JsonFast::extract($json, ['user.name', 'user.email', 'missing']);
// ['user.name' => 'Allan', 'user.email' => '...', 'missing' => null]Deep-merges two JSON documents. Overlay values win on conflict.
Infers a JSON Schema from a document.
Validates JSON against a schema.
Example return value:
[
'valid' => false,
'errors' => [
'$.id expected integer, got string',
],
]Applies schema defaults and strips undeclared properties.
Returns structural differences between two JSON documents.
Example return value:
[
'added' => ['$.role' => 'admin'],
'removed' => [],
'changed' => [
'$.active' => ['from' => true, 'to' => false],
],
]Diffs two JSON Schema documents.
Download the latest Linux or Windows build and load it in PHP without compiling from source.
- Download and extract the release archive:
curl -LO https://github.com/AllanGallop/libphp_jsonfast/releases/latest/download/php_jsonfast-linux-x86_64-php83.zip
unzip php_jsonfast-linux-x86_64-php83.zipThis produces php_jsonfast-linux-x86_64-php83.so along with stubs and documentation.
- Copy the library to a permanent location:
sudo mkdir -p /usr/local/lib/php/extensions/no-debug-non-zts-20230831
sudo cp php_jsonfast-linux-x86_64-php83.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/Adjust the destination directory to match your PHP API version. Run
php -i | grep extension_dirto find the correct path.
- Enable the extension in
php.ini:
extension=php_jsonfast-linux-x86_64-php83.soOr reference the full path:
extension=/usr/local/lib/php/extensions/no-debug-non-zts-20230831/php_jsonfast-linux-x86_64-php83.so- Restart PHP-FPM, Apache, or your CLI shell session if needed, then verify:
php -m | grep jsonfast
php -r "var_dump(class_exists('JsonFast'));"Load directly for a one-off command:
php -d extension=./php_jsonfast-linux-x86_64-php83.so -r "var_dump(JsonFast::validate('{\"ok\":true}'));"Current release artifacts target Linux and Windows x86_64 with PHP 8.3 (non-thread-safe). macOS builds may be added later.
- Download and extract the release archive:
Invoke-WebRequest -Uri "https://github.com/AllanGallop/libphp_jsonfast/releases/latest/download/php_jsonfast-windows-x86_64-php83.zip" -OutFile php_jsonfast.zip
Expand-Archive php_jsonfast.zip -DestinationPath .This produces php_jsonfast-windows-x86_64-php83.dll along with stubs and documentation.
- Copy the DLL into your PHP extensions directory. Find it with:
php -i | findstr extension_dirTypical path for PHP 8.3 NTS x64:
C:\php\ext
Copy-Item php_jsonfast-windows-x86_64-php83.dll C:\php\ext\php_jsonfast.dll- Enable the extension in
php.ini:
extension=php_jsonfast.dll- Verify:
php -m | findstr jsonfast
php -r "var_dump(class_exists('JsonFast'));"Load directly for a one-off command:
php -d extension=.\php_jsonfast-windows-x86_64-php83.dll -r "var_dump(JsonFast::validate('{\"ok\":true}'));"Windows builds require the same PHP variant as the release: PHP 8.3 x64 NTS from windows.php.net. Thread-safe (TS) PHP needs a matching TS build (not yet published).
Install from the .deb attached to the latest GitHub release (replace 1.X.X-1 with latest version):
curl -LO https://github.com/AllanGallop/libphp_jsonfast/releases/latest/download/php-jsonfast_1.X.X-1_amd64.deb
sudo apt install ./php-jsonfast_1.X.X-1_amd64.debVerify:
php -m | grep jsonfast
php -r "var_dump(class_exists('JsonFast'));"The package installs the shared library and drop-in configuration under /etc/php/... so the extension is enabled for CLI and FPM where supported.
Requirements:
- Rust stable on Linux/macOS; Rust nightly on Windows (for
abi_vectorcall) - PHP 8.x development headers (provided by
ext-php-rsbuild) libclang(for bindgen on Linux/macOS/Windows)- On Windows: PHP from windows.php.net and Visual Studio Build Tools (
cl.exe)
cargo build --releaseOn Windows:
rustup toolchain install nightly
cargo +nightly build --releaseLoad the built extension:
; Linux
extension=/path/to/libphp_jsonfast/target/release/libphp_jsonfast.so
; macOS
extension=/path/to/libphp_jsonfast/target/release/libphp_jsonfast.dylib
; Windows
extension=/path/to/libphp_jsonfast/target/release/php_jsonfast.dllGenerate PHP stubs:
make stubs
# or (Linux/macOS: requires libphp embed and LD_PRELOAD)
LD_LIBRARY_PATH=/usr/lib LD_PRELOAD=/usr/lib/libphp.so \
cargo build && cargo php stubs target/debug/libphp_jsonfast.so --stdout > php_jsonfast.stub.phpInstall PHP benchmark dependencies:
composer installThis repository includes a Dockerfile with PHP, Composer, Rust, and cargo-php.
Build the image:
docker compose buildOpen a shell:
docker compose run --rm php-rust bashBuild, test, examples, and benchmark inside the container:
make test
make examples
make benchmarkOne-shot from the host (builds the image, runs tests + examples):
docker compose run --rm run-checks
docker compose run --rm run-examples
docker compose run --rm run-testsFrom packaging/docker (same Ubuntu PHP 8.3 dev image, cached cargo/target volumes):
cd packaging/docker
docker compose run --rm dev-php83
docker compose run --rm dev-shellRunnable scripts live under examples/. Each file focuses on one area of the API.
| Script | Topics |
|---|---|
01_format_and_validate.php |
validate, beautify, minify, output modes |
02_repair_and_unwrap.php |
analyse, repair, inspect, unwrap |
03_path_access.php |
get, has, search, extract |
04_merge_and_diff.php |
merge, diff |
05_schema.php |
getSchema, validateSchema, applySchema, schemaDiff |
Run everything (extension must be built first):
make examples
# or
php -d extension=target/release/libphp_jsonfast.so examples/run_all.php
php -d extension=target/release/libphp_jsonfast.so examples/03_path_access.php<?php
$json = '{"name":"Allan","active":true,"roles":["admin","user"]}';
//--------------------------------------------------------------------//
// Default: PHP array
$data = JsonFast::minify($json);
// ['name' => 'Allan', 'active' => true, 'roles' => [...]]
//--------------------------------------------------------------------//
// JSON string output
$compact = JsonFast::minify($json, JsonFast::OUTPUT_STRING);
//--------------------------------------------------------------------//
// Object output (stdClass)
$object = JsonFast::minify($json, JsonFast::OUTPUT_OBJECT);
echo $object->name;
//--------------------------------------------------------------------//
// Repair broken JSON
$broken = <<<'JSON'
{
// user profile
"name": Allan,
"active": true,
}
JSON;
$fixed = JsonFast::repair($broken, JsonFast::REPAIR_ALL, JsonFast::OUTPUT_STRING);
//--------------------------------------------------------------------//
// Path access
$userJson = '{"user":{"name":"Allan","profile":{"city":"Milton Keynes"}}}';
echo JsonFast::get($userJson, 'user.profile.city'); // Milton Keynes
echo JsonFast::has($userJson, 'user.missing') ? 'yes' : 'no'; // no
//--------------------------------------------------------------------//
// Merge and diff
$merged = JsonFast::merge(
'{"name":"Allan","settings":{"theme":"dark"}}',
'{"active":false,"settings":{"language":"en"}}'
);
$changes = JsonFast::diff(
'{"name":"Allan","active":true}',
'{"name":"Allan","active":false,"role":"admin"}'
);
//--------------------------------------------------------------------//
// Schema
$schema = JsonFast::getSchema($json, JsonFast::OUTPUT_STRING);
$result = JsonFast::validateSchema($json, $schema);Run the full PHP test suite:
make testIndividual test targets:
make test-basic
make test-output
make test-path
make test-analyse-repair
make test-schema
make test-diffRun with coverage (requires pcov or xdebug):
make coverageRun the comparison benchmark suite:
make benchmarkCustom parameters:
php -d extension=target/release/libphp_jsonfast.so \
benchmarks/benchmark.php [iterations] [medium_items] [max_capacity_items]Benchmark dependencies (installed via Composer):
opis/json-schemajustinrainbow/json-schema
- Schema validation implements a partial subset of JSON Schema (types,
required,properties,items,default) — not the full draft spec. - Path wildcards are supported in
search()(users[*].email), not inget(). OUTPUT_STRINGonbeautify()preserves the requested indent; other methods return compact JSON strings.OUTPUT_OBJECTmaps JSON objects tostdClass; JSON arrays remain PHP arrays.- Current development targets PHP 8.x via
ext-php-rs0.15.
src/— Rust source for the PHP extensionsrc/lib.rs—JsonFastclass and module entrytests/— PHP integration testsbenchmarks/— comparison benchmarks against native PHP and schema libraries.github/images/— README benchmark chartsCargo.toml— Rust crate metadata and dependenciescomposer.json— PHP benchmark/test dependenciesDockerfile— container environment for building and testingdocker-compose.yaml— local Docker workflowMakefile— build, test, stub, coverage, and benchmark commands


