Why JsonFast?
Most PHP JSON workflows combine json_decode(), manual array walking, and third-party libraries for schema validation. php_jsonfast consolidates these into a single Rust-backed extension.
Features
- Analyse invalid JSON — exact error location for logging and user-facing feedback
- Unwrap double- or triple-encoded JSON strings recursively, without manual
json_decode()loops - 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
Compared to the usual PHP stack
| Concern | Typical approach | JsonFast |
|---|---|---|
| "Why did this fail?" | Trial-and-error json_decode() or logging raw bytes | analyse() or inspect() — line, column, and message |
| Double-encoded payloads | Repeated json_decode() until not a string | unwrap() with configurable depth |
| Nested reads | json_decode() + array walks | get(), has(), search(), extract() |
| Schema | Composer packages (Opis, JustinRainbow, …) | validateSchema(), getSchema(), applySchema() |
| Diff / merge | Userland helpers | diff(), merge(), schemaDiff() |
| Output shape | Re-encode or cast manually | OUTPUT_ARRAY, OUTPUT_STRING, OUTPUT_OBJECT |
Better errors than json_decode()
json_decode() only answers valid or not. When imports, webhooks, or log pipelines fail, you usually need more:
- Where did parsing break? (
analyse()andinspect()return line and column.) - What went wrong? A structured error message you can log or show in the UI.
That matters for safer ingestion (reject bad payloads with context) or UI that shows users why their upload failed.
Peel double-encoded JSON
A surprisingly common production bug: the outer document decodes fine, but the value you need is still a JSON string. That happens when:
- An API JSON-encodes a payload that was already a string
- A column stores
json_encode(json_encode($data)) - A queue or webhook wraps the body again for transport
In PHP that often becomes a fragile loop:
php
while (is_string($decoded)) {
$decoded = json_decode($decoded, true);
}unwrap() does that in one native call, up to $maxDepth, with the same output modes as every other method.
Built on solid foundations
- 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
- Built on
serde_jsonwith order-preserving object keys