Skip to content

API — Types & Internals — PHP

Table of Contents

PluginRegistry

Namespace: SafeAccessInline\Core\Registries\PluginRegistry

Static registry for parser and serializer plugins. Parsers convert raw strings to arrays; serializers convert arrays to formatted strings.

PluginRegistry::registerParser(string $format, ParserPluginInterface $parser): void

Register a parser plugin for the given format.

php
use SafeAccessInline\Plugins\SymfonyYamlParser;
PluginRegistry::registerParser('yaml', new SymfonyYamlParser());

PluginRegistry::registerSerializer(string $format, SerializerPluginInterface $serializer): void

Register a serializer plugin for the given format.

php
use SafeAccessInline\Plugins\SymfonyYamlSerializer;
PluginRegistry::registerSerializer('yaml', new SymfonyYamlSerializer());

PluginRegistry::hasParser(string $format): bool

Check if a parser is registered for the given format.

PluginRegistry::hasSerializer(string $format): bool

Check if a serializer is registered for the given format.

PluginRegistry::getParser(string $format): ParserPluginInterface

Get the registered parser. Throws UnsupportedTypeException if not registered.

PluginRegistry::getSerializer(string $format): SerializerPluginInterface

Get the registered serializer. Throws UnsupportedTypeException if not registered.

PluginRegistry::reset(): void

Clear all registered plugins. Intended for testing — call in beforeEach to prevent cross-test pollution.

Plugin Interfaces

ParserPluginInterface

Namespace: SafeAccessInline\Contracts\ParserPluginInterface

php
interface ParserPluginInterface
{
    /**
     * @param string $raw
     * @return array<mixed>
     * @throws InvalidFormatException
     */
    public function parse(string $raw): array;
}

SerializerPluginInterface

Namespace: SafeAccessInline\Contracts\SerializerPluginInterface

php
interface SerializerPluginInterface
{
    /**
     * @param array<mixed> $data
     * @return string
     */
    public function serialize(array $data): string;
}

PathCache

Namespace: SafeAccessInline\Core\PathCache

An internal LRU-style cache for parsed dot-notation path segments. Exported for advanced use cases such as pre-warming the cache or clearing it between test runs. All methods are static.

PathCache::get(string $path): ?array

Retrieve cached parsed segments for the given path string.

PathCache::set(string $path, array $segments): void

Store parsed segments in the cache.

PathCache::has(string $path): bool

Check if a path is cached.

PathCache::clear(): void

Evict all entries from the cache.

PathCache::size(): int

Return the current number of cached entries.

PathCache::enable(): void

Enable the cache (enabled by default).

PathCache::disable(): void

Disable the cache — all lookups will bypass the cache.

PathCache::isEnabled(): bool

Check if the cache is currently enabled.


DotNotationParser

Namespace: SafeAccessInline\Core\Parsers\DotNotationParser

Static utility class. Typically used internally, but available for direct use.

DotNotationParser::get(array $data, string $path, mixed $default = null): mixed

Supports advanced path expressions:

SyntaxDescriptionExample
a.b.cNested key access"user.profile.name"
a[0]Bracket index"items[0].title"
a.*Wildcard — returns array of values"users.*.name"
a[?field>value]Filter — returns matching items"products[?price>20]"
..keyRecursive descent — collects all values of key at any depth"..name"

Filter expressions support:

  • Comparison: ==, !=, >, <, >=, <=
  • Logical: && (AND), \|\| (OR)
  • Values: numbers, 'strings', true, false, null
php
// Filter: all admin users
DotNotationParser::get($data, "users[?role=='admin']");

// Filter with numeric comparison + path continuation
DotNotationParser::get($data, 'products[?price>20].name');

// Combined AND
DotNotationParser::get($data, "items[?type=='fruit' && color=='red'].name");

// Recursive descent: all "name" values at any depth
DotNotationParser::get($data, '..name');

// Descent + wildcard
DotNotationParser::get($data, '..items.*.id');

// Descent + filter
DotNotationParser::get($data, "..employees[?active==true].name");

DotNotationParser::has(array $data, string $path): bool

DotNotationParser::set(array $data, string $path, mixed $value): array

Returns a new array (does not mutate input).

DotNotationParser::merge(array $data, string $path, array $value): array

Deep merges $value at $path. When $path is empty, merges at root. Associative arrays are merged recursively; other values are replaced.

php
$result = DotNotationParser::merge($data, 'user.settings', ['theme' => 'dark']);

DotNotationParser::remove(array $data, string $path): array

Returns a new array (does not mutate input).

DotNotationParser::renderTemplate(string $template, array $bindings): string

Renders {key} placeholders in a path template.

php
DotNotationParser::renderTemplate('users.{id}.name', ['id' => '42']);
// 'users.42.name'

Exceptions

ExceptionWhen
AccessorExceptionBase exception class
InvalidFormatExceptionInvalid input format (e.g., malformed JSON, missing parser plugin at accessor level)
UnsupportedTypeExceptiondetect() cannot determine format; PluginRegistry has no registered plugin; toXml()/transform() has no serializer
PathNotFoundExceptionReserved (not thrown by get())
SecurityExceptionSSRF attempt, path traversal, payload too large, forbidden keys, CSV injection (error mode)
ReadonlyViolationExceptionModifying a readonly accessor (set, remove, merge, push, etc.)
SchemaValidationExceptionSchema validation failed — has getIssues(): SchemaValidationIssue[] for detailed error info
JsonPatchTestFailedExceptionJSON Patch test operation failed — value at path does not match expected value

Interfaces

InterfaceMethods
ReadableInterfaceget(), getMany(), all()
WritableInterfaceset(), merge(), remove()
TransformableInterfacetoArray(), toJson(), toXml(), toYaml(), toToml(), toNdjson(), toObject(), transform()
AccessorInterfaceExtends ReadableInterface + TransformableInterface, adds from(), has(), type(), count(), keys()
ParserPluginInterfaceparse()
SerializerPluginInterfaceserialize()
SchemaAdapterInterfacevalidate()

Enums

AccessorFormat

Namespace: SafeAccessInline\Enums\AccessorFormat

String-backed enum covering all built-in formats. Use it as a type-safe alternative to passing raw strings to SafeAccess::from().

CaseValue
AccessorFormat::Array'array'
AccessorFormat::Object'object'
AccessorFormat::Json'json'
AccessorFormat::Xml'xml'
AccessorFormat::Yaml'yaml'
AccessorFormat::Toml'toml'
AccessorFormat::Ini'ini'
AccessorFormat::Csv'csv'
AccessorFormat::Env'env'
AccessorFormat::Ndjson'ndjson'

Released under the MIT License.