JSON Pointer (RFC 6901) Resolver
PHP Code Editor
Execution Result
Ready to execute
Click the "Run Script" button to see the output here
Description
JSON Pointer is the small standard behind references in JSON Schema, JSON Patch, and many config formats. A pointer like /servers/0/host is a path into a decoded document. It looks like simple string splitting until you hit the escaping rules, where a literal slash inside a key is written ~1 and a literal tilde is written ~0, and the unescape order matters or you corrupt keys that contain both.
This resolver splits the pointer on slashes, unescapes each segment by replacing ~1 before ~0, then descends one level at a time, handling both associative arrays and stdClass objects so it works whether you decoded with associative true or false. An empty pointer is defined by the RFC to mean the whole document, and any segment that does not exist raises an out-of-bounds error rather than silently returning null.
function jsonPointerGet(array|object $doc, string $pointer): mixed {
if ($pointer === '') {
return $doc;
}
if ($pointer[0] !== '/') {
throw new InvalidArgumentException('Pointer must start with /');
}
$current = $doc;
foreach (explode('/', substr($pointer, 1)) as $rawToken) {
$token = str_replace(['~1', '~0'], ['/', '~'], $rawToken);
if (is_array($current) && array_key_exists($token, $current)) {
$current = $current[$token];
} elseif (is_object($current) && property_exists($current, $token)) {
$current = $current->$token;
} else {
throw new OutOfBoundsException("No value at: $pointer");
}
}
return $current;
}
$doc = json_decode('{"servers":[{"host":"a.example"},{"host":"b.example"}],"a/b":42}', true);
echo jsonPointerGet($doc, '/servers/1/host') . "\n"; // b.example
echo jsonPointerGet($doc, '/a~1b') . "\n"; // 42 (key "a/b")
Comments
No comments yet
Be the first to share your thoughts!