alto/json-patch
Composer 安装命令:
composer require alto/json-patch
包简介
A PHP JSON-Patch library based on RFC 6902 for generating smart diffs, applying patches, and rebuilding data structures.
关键字:
README 文档
README
A strict, auditable JSON Patch implementation for PHP 8.3+. This library handles two concerns with precision:
- Apply: A deterministic RFC 6902 engine that replays patches exactly.
- Diff: A smart diff generator that produces stable, readable patches.
Built for systems where change history matters.
- Pure PHP: Tiny surface area, no heavy dependencies.
- Strict Types: Built for PHP 8.3+ with strict typing.
- Deterministic: Error model designed for auditability.
- Smart Diffing: Supports standard list replacement or smart "by-id" list diffing for readable patches.
Installation
composer require alto/json-patch
Why Alto JSON Patch?
For audit logs: Deterministic apply means you can verify patch integrity. Store the parent hash, the patch, and the result hash. Replaying the patch will always produce the same result.
For readable diffs: Generate clean patches that humans can review. Optional identity-based list diffing produces granular operations instead of replacing entire arrays.
For reliability: Pure PHP with strict types. No magic, no surprises.
Quick Start
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); // ['user' => ['name' => 'Alice', 'role' => 'admin'], 'status' => 'published']
Generate Patches
Create patches automatically by diffing two states:
$before = ['version' => 1, 'status' => 'draft']; $after = ['version' => 2, 'status' => 'published', 'author' => 'Alice']; $patch = JsonPatch::diff($before, $after); // [ // ['op' => 'replace', 'path' => '/version', 'value' => 2], // ['op' => 'replace', 'path' => '/status', 'value' => 'published'], // ['op' => 'add', 'path' => '/author', 'value' => 'Alice'], // ]
Smart List Diffing
By default, lists are replaced entirely when they differ. For granular control, use identity-based diffing:
use Alto\JsonPatch\DiffOptions; $before = [ 'items' => [ ['id' => 'a', 'qty' => 1], ['id' => 'b', 'qty' => 2], ], ]; $after = [ 'items' => [ ['id' => 'b', 'qty' => 3], // Modified and reordered ['id' => 'c', 'qty' => 1], // Added ], ]; $options = new DiffOptions(['/items' => 'id']); $patch = JsonPatch::diff($before, $after, $options); // Generates move, add, remove, and replace operations for individual items
This produces readable patches where reviewers can see exactly which items changed.
Utility Methods
// Get a value at a JSON pointer path $name = JsonPatch::get($document, '/user/name'); // Test if a value matches (returns bool) $isAdmin = JsonPatch::test($document, '/user/role', 'admin'); // Validate patch structure without applying $errors = JsonPatch::validate($patch);
Audit Trail Example
class ChangeLog { public function recordChange(array $before, array $after): void { $patch = JsonPatch::diff($before, $after); $this->store([ 'parent_hash' => hash('sha256', json_encode($before)), 'patch' => $patch, 'result_hash' => hash('sha256', json_encode($after)), 'timestamp' => time(), ]); } public function verifyIntegrity(string $recordId): bool { $record = $this->fetch($recordId); $parent = $this->reconstructState($record['parent_hash']); $result = JsonPatch::apply($parent, $record['patch']); $computedHash = hash('sha256', json_encode($result)); return $computedHash === $record['result_hash']; } }
Supported Operations
All RFC 6902 operations:
add: Add a value at a pathremove: Remove a value at a pathreplace: Replace a value at a pathmove: Move a value from one path to anothercopy: Copy a value from one path to anothertest: Assert a value matches (useful for conditional patches)
Error Handling
Operations throw JsonPatchException with clear messages:
try { JsonPatch::apply($doc, $patch); } catch (JsonPatchException $e) { // "Operation 0 (replace): path '/missing/path' not found." // "Operation 1 (add): invalid path '/items/-1'." }
Advanced Usage
Float Comparison
JsonPatch uses strict equality (===) for values. Be aware that json_decode may treat numbers differently depending on flags.
For example, 1.0 (float) is not strictly equal to 1 (int). Ensure your input documents use consistent types if strict equality is required.
Limitations
applyJson: Empty Object vs Array
When using JsonPatch::applyJson(), the underlying json_decode converts empty JSON objects {} into empty PHP arrays
[].
Since PHP does not distinguish between empty associative arrays (objects) and empty indexed arrays (lists), an input of
{"key": {}} may result in {"key": []} after a round-trip.
If strictly preserving {} vs [] is critical, consider using apply() with pre-decoded structures where you can
control the object mapping (e.g. json_decode($json, false) for stdClass).
API Reference
JsonPatch
| Method | Description |
|---|---|
apply(array $doc, array $patch): array |
Apply a patch to a document |
applyJson(string $docJson, string $patchJson, int $flags = 0): string |
Apply patch to JSON string |
diff(array $from, array $to, ?DiffOptions $opts = null): array |
Generate patch from two states |
get(array $doc, string $path): mixed |
Get value at JSON pointer path |
test(array $doc, string $path, mixed $value): bool |
Test if value matches at path |
validate(array $patch): array |
Validate patch structure, returns errors |
DiffOptions
Configure identity-based list diffing:
$options = new DiffOptions([ '/users' => 'id', // Use 'id' field for /users array '/items' => 'sku', // Use 'sku' field for /items array ]);
License
This project is licensed under the MIT License - see the LICENSE file for details.
alto/json-patch 适用场景与选型建议
alto/json-patch 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 3 次下载、GitHub Stars 达 2, 最近一次更新时间为 2026 年 01 月 17 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「json」 「state」 「diff」 「Audit」 「versioning」 「deterministic」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 alto/json-patch 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 alto/json-patch 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 alto/json-patch 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A library for comparing two HTML files/snippets and highlighting the differences using simple HTML.
Doctrine implementation of the MetaborStd (Statemachine) for PHP 8.2+
Kinikit - PHP Application development framework MVC component
A simple state dropdown field for SilverStripe forms
Schema Diff: Show difference between MySQL databases
统计信息
- 总下载量: 3
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 2
- 点击次数: 36
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-17