Dot Notation#

Infocyph\ArrayKit\Array\DotNotation is the core nested access utility used across ArrayKit.

It supports:

  • dot-path reads/writes (user.profile.name)

  • multi-key reads and bulk set/fill

  • wildcard traversal in reads and forget operations

  • typed accessors with exceptions

  • flatten/expand conversion

Basic Get/Set#

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$data = ['user' => ['profile' => ['name' => 'Alice']]];

$name = DotNotation::get($data, 'user.profile.name'); // Alice
$missing = DotNotation::get($data, 'user.profile.email', 'n/a'); // n/a

DotNotation::set($data, 'user.profile.email', '[email protected]');

// Replace entire array (key = null)
DotNotation::set($data, null, ['fresh' => true]);

Literal Dot Keys (Escaped Paths)#

Use \\. inside a path segment to target literal key dots:

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$data = ['service.name' => 'ArrayKit'];

$name = DotNotation::get($data, 'service\\.name'); // ArrayKit
DotNotation::set($data, 'service\\.env', 'prod');
DotNotation::forget($data, 'service\\.env');

Reading Multiple Keys#

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$data = [
    'app' => ['name' => 'ArrayKit', 'env' => 'local'],
    'db' => ['host' => 'localhost'],
];

$result = DotNotation::get($data, ['app.name', 'db.host'], 'default');
// [
//   'app.name' => 'ArrayKit',
//   'db.host' => 'localhost',
// ]

Fill vs Set#

set() writes values normally. fill() only writes when key is missing.

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$data = ['app' => ['env' => 'prod']];

DotNotation::set($data, 'app.env', 'local');    // overwrite -> local
DotNotation::fill($data, 'app.env', 'staging'); // does not overwrite
DotNotation::fill($data, 'app.debug', true);    // writes

Object properties (including null-valued properties) are treated as existing when filling:

<?php
$data = ['user' => (object) ['middle_name' => null]];
DotNotation::fill($data, 'user.middle_name', 'X');
// remains null; existing null property is not considered missing

Bulk Set/Fill#

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$data = [];

DotNotation::set($data, [
    'user.name' => 'Alice',
    'user.email' => '[email protected]',
]);

DotNotation::fill($data, [
    'user.name' => 'Bob',          // ignored
    'user.role' => 'admin',        // added
]);

Existence Checks#

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$data = ['user' => ['name' => 'Alice']];

$has = DotNotation::has($data, 'user.name'); // true
$hasBoth = DotNotation::has($data, ['user.name', 'user.email']); // false
$hasAny = DotNotation::hasAny($data, ['x.y', 'user.name']); // true

Forgetting Keys#

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$data = [
    'users' => [
        ['name' => 'A', 'secret' => 'x'],
        ['name' => 'B', 'secret' => 'y'],
    ],
];

// Remove one nested path
DotNotation::forget($data, 'users.0.secret');

// Wildcard remove (all users.*.secret)
DotNotation::forget($data, 'users.*.secret');

Wildcards and Special Segments in get()#

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$data = [
    'users' => [
        ['name' => 'Alice'],
        ['name' => 'Bob'],
    ],
];

$names = DotNotation::get($data, 'users.*.name'); // ['Alice', 'Bob']
$first = DotNotation::get($data, 'users.{first}.name'); // Alice
$last = DotNotation::get($data, 'users.{last}.name');   // Bob

Wildcard and Path Utilities#

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$data = [
    'users' => [
        ['name' => 'Alice', 'email' => '[email protected]'],
        ['name' => 'Bob', 'email' => '[email protected]'],
    ],
];

$hasWildcard = DotNotation::hasWildcard('users.*.email'); // true
$allPaths = DotNotation::paths($data); // ['users.0.name', ...]
$matched = DotNotation::matches($data, 'users.*.email'); // true

DotNotation::rename($data, 'users.0.name', 'users.0.full_name');
DotNotation::move($data, 'users.1.email', 'contacts.secondary');

Safe Traversal Limits#

Use getSafe() when path traversal depth or node count must be bounded.

<?php
$value = DotNotation::getSafe($data, 'users.*.email', 'missing', maxDepth: 8, maxNodes: 50000);

Flatten and Expand#

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$flat = DotNotation::flatten([
    'user' => ['name' => 'Alice', 'email' => '[email protected]'],
]);
// [
//   'user.name' => 'Alice',
//   'user.email' => '[email protected]',
// ]

$expanded = DotNotation::expand($flat);

Typed Accessors#

Typed helpers enforce value type and throw InvalidArgumentException on mismatch.

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$cfg = [
    'app' => ['name' => 'ArrayKit', 'debug' => true],
    'port' => 8080,
    'ratio' => 0.75,
];

$name = DotNotation::string($cfg, 'app.name');
$debug = DotNotation::boolean($cfg, 'app.debug');
$port = DotNotation::integer($cfg, 'port');
$ratio = DotNotation::float($cfg, 'ratio');

ArrayAccess-style Helpers#

DotNotation also exposes static offset* methods:

<?php
use Infocyph\ArrayKit\Array\DotNotation;

$data = [];
DotNotation::offsetSet($data, 'a.b', 1);
$exists = DotNotation::offsetExists($data, 'a.b'); // true
$value = DotNotation::offsetGet($data, 'a.b');     // 1
DotNotation::offsetUnset($data, 'a.b');

Behavior Notes#

  • get($array, null) returns the full array.

  • Existing keys with null values return null (not the default).

  • Existing object properties with null values are also treated as present.

  • Missing integer keys return the provided default.

  • Defaults may be plain values or callables, and callables are only evaluated when path resolution fails.

  • Wildcard traversal in get returns arrays of matched results.

  • set supports wildcard paths when wildcard is the first segment.

  • forget supports wildcard and nested removal across arrays.