alto / json-patch
Strict RFC 6902 patching and deterministic diffs for PHP.
Fund package maintenance!
Requires
- php: ^8.3
- ext-json: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Strict RFC 6902 patching and deterministic diffs for PHP.
ALTO JSON Patch applies all six JSON Patch operations and generates stable patches between PHP values. Its identity-aware list diffing can express moves and nested changes instead of replacing complete lists, keeping generated patches compact and readable.
use Alto\JsonPatch\JsonPatch; $before = ['status' => 'draft', 'tags' => ['php']]; $after = ['status' => 'published', 'tags' => ['php', 'json']]; $patch = JsonPatch::diff($before, $after); $result = JsonPatch::apply($before, $patch); assert($after === $result);
The package has no runtime dependencies beyond PHP's JSON extension. Its test suite includes the RFC 6902 compliance corpus, and the codebase is analyzed at PHPStan level 10.
Installation
Install ALTO JSON Patch with Composer:
composer require alto/json-patch
ALTO JSON Patch requires PHP 8.3 or later and the JSON extension. The extension ships with PHP.
Quick Start
Apply a sequence of operations to an in-memory value:
use Alto\JsonPatch\JsonPatch; $document = [ 'user' => ['name' => 'Alice', 'role' => 'editor'], 'status' => 'draft', ]; $patch = [ ['op' => 'replace', 'path' => '/user/role', 'value' => 'admin'], ['op' => 'replace', 'path' => '/status', 'value' => 'published'], ]; $result = JsonPatch::apply($document, $patch); echo json_encode($result, JSON_THROW_ON_ERROR);
The original value is unchanged. Operations run in order, and each operation sees the result of the preceding one. The example prints:
{"user":{"name":"Alice","role":"admin"},"status":"published"}
Documentation
The documentation index lists these pages in site navigation order.
Operations
JsonPatch::apply() supports every RFC 6902 operation:
| Operation | Effect |
|---|---|
add |
Insert or replace a value |
remove |
Delete an existing value |
replace |
Replace an existing value |
move |
Move a value to another path |
copy |
Copy a value to another path |
test |
Assert that a value matches |
Use JsonPatch::applyJson() to work directly with JSON strings. Read
Operations for ordered semantics, validation, and JSON
handling. Errors covers runtime failures and recovery.
Generating Patches
Generate the operations needed to transform one state into another:
$patch = JsonPatch::diff( ['version' => 1, 'status' => 'draft'], ['version' => 2, 'status' => 'published'], );
Object keys are compared recursively. Lists use a longest common subsequence by default, producing
stable add and remove operations while preserving unchanged items.
Identity-aware Lists
Configure an identity key to express item moves and nested changes:
use Alto\JsonPatch\DiffOptions; $options = new DiffOptions( listIdentityByPointer: ['/items' => 'id'], ); $patch = JsonPatch::diff($before, $after, $options);
Read Generating patches for list strategies and their fallback behavior.
JSON Pointers
Patch paths follow RFC 6901. Use JsonPatch::get() and JsonPatch::test() to inspect values at a
path, or Pointer when another component needs to parse and compose paths.
$name = JsonPatch::get($document, '/user/name'); $isAdmin = JsonPatch::test($document, '/user/role', 'admin');
Read JSON Pointers for root paths, list indices, and escaping. The complete guide also covers installation and a first end-to-end patch.
Contributing
Contributions of all kinds are welcome. Visit the project on GitHub to report a bug, suggest a feature, or open a pull request.
Before submitting code, run:
# Runs PHP CS Fixer, PHPStan, and PHPUnit
composer qa
Changes to public behavior should include tests and documentation.
Support
ALTO JSON Patch is open source and independently maintained by Simon André. If it is useful to your work, you can support its continued development through GitHub Sponsors.
Sharing the package or starring it on GitHub also helps.
License
ALTO JSON Patch is released by ALTO PHP under the MIT License.