ergebnis/json-pointer
RFC 6901 JSON Pointer abstraction for PHP. Create and convert reference tokens and pointers from plain strings, JSON string form, or URI fragment identifiers, with correct escaping and encoding. Install via Composer and use small, typed value objects.
Installation:
composer require ergebnis/json-pointer
Add to composer.json if using a monorepo or custom setup.
First Use Case: Navigate to a nested JSON value using RFC 6901-compliant pointers:
use Ergebnis\Json\Pointer;
$pointer = Pointer\ReferenceToken::fromString('/user/address/city');
$value = $pointer->getValueFrom(json_decode($jsonString, true));
Key Classes:
ReferenceToken: Core class for pointer operations.PointerException: Handle invalid pointers or missing keys.PointerBuilder: For constructing pointers programmatically.tests/ for edge cases.Pointer Creation:
// From string (RFC 6901 format)
$token = Pointer\ReferenceToken::fromString('/a/b/c');
// From array (programmatic)
$token = Pointer\PointerBuilder::create()->add('a')->add('b')->add('c')->build();
Value Extraction:
$data = ['a' => ['b' => ['c' => 'value']]];
$value = $token->getValueFrom($data); // Returns 'value'
Validation:
if ($token->isValid()) {
$value = $token->getValueFrom($data);
}
Modification:
$token->setValueOn($data, 'new_value'); // Mutates $data
Laravel Collections:
use Illuminate\Support\Collection;
$collection = collect($data);
$value = $token->getValueFrom($collection->toArray());
API Responses: Validate incoming JSON pointers in request payloads:
$request->validate([
'pointer' => ['required', 'string', function ($attribute, $value, $fail) {
try {
Pointer\ReferenceToken::fromString($value);
} catch (PointerException $e) {
$fail('Invalid JSON pointer.');
}
}]
]);
Dynamic Pointers: Build pointers from user input or config:
$path = config('dynamic.path');
$token = Pointer\PointerBuilder::create()->add($path)->build();
Invalid Pointers:
/a//b) throw PointerException.try-catch or isValid() before use.Non-Array Data:
getValueFrom() may fail.$token->getValueFrom((array) $data);
Tilde Encoding:
~ (e.g., /a~1b) require URL-encoding.Pointer\ReferenceToken::fromString() or encode manually:
$encoded = str_replace('~', '~0', $path);
Mutability:
setValueOn() modifies the input array by reference. Use caution in shared contexts.Inspect Tokens:
$token->getPath(); // Returns ['a', 'b', 'c']
$token->__toString(); // Returns '/a/b/c'
Log Pointers:
\Log::debug('Pointer path:', ['path' => $token->getPath()]);
Custom Validators:
Extend Pointer\ReferenceToken to add domain-specific rules:
class CustomToken extends ReferenceToken {
public function isAllowed(array $data): bool {
return in_array($this->getPath()[0], ['allowed', 'keys']);
}
}
Pointer Events: Listen for pointer operations (e.g., via events or decorators):
$token->getValueFrom($data, function ($path) {
\Log::info("Accessing path: " . implode('/', $path));
});
Performance:
$cachedToken = Pointer\ReferenceToken::fromString('/deep/nested/path');
No Default Config:
The package is stateless; no config/json-pointer.php exists. All behavior is runtime-driven.
Type Safety:
declare(strict_types=1) to enforce type hints (e.g., getValueFrom(array $data): mixed).How can I help you explore Laravel packages today?